Merge branch 'master' into release/2.4
This commit is contained in:
commit
64e3aff65b
98
environment/os/fedora-36.sh
Executable file
98
environment/os/fedora-36.sh
Executable file
@ -0,0 +1,98 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source "$DIR/../util.sh"
|
||||
|
||||
check_operating_system "fedora-36"
|
||||
check_architecture "x86_64"
|
||||
|
||||
TOOLCHAIN_BUILD_DEPS=(
|
||||
coreutils-common gcc gcc-c++ make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg2 # used for archive signature verification
|
||||
tar gzip bzip2 xz unzip # used for archive unpacking
|
||||
zlib-devel # zlib library used for all builds
|
||||
expat-devel xz-devel python3-devel texinfo libbabeltrace-devel # for gdb
|
||||
curl libcurl-devel # for cmake
|
||||
readline-devel # for cmake and llvm
|
||||
libffi-devel libxml2-devel # for llvm
|
||||
libedit-devel pcre-devel automake bison # for swig
|
||||
file
|
||||
openssl-devel
|
||||
gmp-devel
|
||||
gperf
|
||||
diffutils
|
||||
libipt libipt-devel # intel
|
||||
patch
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz # used for archive unpacking
|
||||
zlib # zlib library used for all builds
|
||||
expat xz-libs python3 # for gdb
|
||||
readline # for cmake and llvm
|
||||
libffi libxml2 # for llvm
|
||||
openssl-devel
|
||||
perl # for openssl
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkgconf-pkg-config # build system
|
||||
wget # for downloading libs
|
||||
libuuid-devel java-11-openjdk # required by antlr
|
||||
readline-devel # for memgraph console
|
||||
python3-devel # for query modules
|
||||
openssl-devel
|
||||
libseccomp-devel
|
||||
python3 python3-pip python3-virtualenv python3-virtualenvwrapper python3-pyyaml nmap-ncat # for tests
|
||||
libcurl-devel # mg-requests
|
||||
rpm-build rpmlint # for RPM package building
|
||||
doxygen graphviz # source documentation generators
|
||||
which nodejs golang zip unzip java-11-openjdk-devel # for driver tests
|
||||
sbcl # for custom Lisp C++ preprocessing
|
||||
autoconf # for jemalloc code generation
|
||||
libtool # for protobuf code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
local missing=""
|
||||
for pkg in $1; do
|
||||
if ! dnf list installed "$pkg" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
done
|
||||
if [ "$missing" != "" ]; then
|
||||
echo "MISSING PACKAGES: $missing"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
cd "$DIR"
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root."
|
||||
exit 1
|
||||
fi
|
||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||
# Python related tests don't work without the LANG export.
|
||||
if [ -d "/home/gh/actions-runner" ]; then
|
||||
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||
else
|
||||
echo "NOTE: export LANG=en_US.utf8"
|
||||
fi
|
||||
dnf update -y
|
||||
for pkg in $1; do
|
||||
dnf install -y "$pkg"
|
||||
done
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
1
environment/toolchain/.gitignore
vendored
Normal file
1
environment/toolchain/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.tar.gz
|
@ -10,6 +10,14 @@ cd "$DIR"
|
||||
source "$DIR/../util.sh"
|
||||
DISTRO="$(operating_system)"
|
||||
|
||||
function log_tool_name () {
|
||||
echo ""
|
||||
echo ""
|
||||
echo "#### $1 ####"
|
||||
echo ""
|
||||
echo ""
|
||||
}
|
||||
|
||||
for_arm=false
|
||||
if [[ "$#" -eq 1 ]]; then
|
||||
if [[ "$1" == "--for-arm" ]]; then
|
||||
@ -20,9 +28,11 @@ if [[ "$#" -eq 1 ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
os="$1"
|
||||
|
||||
# toolchain version
|
||||
TOOLCHAIN_STDCXX="${TOOLCHAIN_STDCXX:-libstdc++}"
|
||||
if [[ "$TOOLCHAIN_STDCXX" != "libstdc++" && "$TOOLCHAIN_STDCXX" != "libc++" ]]; then
|
||||
echo "Only GCC (libstdc++) or LLVM (libc++) C++ standard library implementations are supported."
|
||||
exit 1
|
||||
fi
|
||||
TOOLCHAIN_VERSION=4
|
||||
|
||||
# package versions used
|
||||
@ -99,6 +109,8 @@ if [ ! -f llvm-$LLVM_VERSION.src.tar.xz ]; then
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libunwind-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libcxx-$LLVM_VERSION.src.tar.xz
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libcxxabi-$LLVM_VERSION.src.tar.xz
|
||||
fi
|
||||
if [ ! -f pahole-gdb-master.zip ]; then
|
||||
wget https://github.com/PhilArmstrong/pahole-gdb/archive/master.zip -O pahole-gdb-master.zip
|
||||
@ -156,6 +168,8 @@ if [ ! -f llvm-$LLVM_VERSION.src.tar.xz.sig ]; then
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libunwind-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libcxx-$LLVM_VERSION.src.tar.xz.sig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libcxxabi-$LLVM_VERSION.src.tar.xz.sig
|
||||
fi
|
||||
# list of valid llvm gnupg keys: https://releases.llvm.org/download.html
|
||||
$GPG --keyserver $KEYSERVER --recv-keys 0x474E22316ABF4785A88C6E8EA2C794A986419D8A
|
||||
@ -165,6 +179,8 @@ $GPG --verify lld-$LLVM_VERSION.src.tar.xz.sig lld-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify compiler-rt-$LLVM_VERSION.src.tar.xz.sig compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify libunwind-$LLVM_VERSION.src.tar.xz.sig libunwind-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify libcxx-$LLVM_VERSION.src.tar.xz.sig libcxx-$LLVM_VERSION.src.tar.xz
|
||||
$GPG --verify libcxxabi-$LLVM_VERSION.src.tar.xz.sig libcxxabi-$LLVM_VERSION.src.tar.xz
|
||||
|
||||
popd
|
||||
|
||||
@ -172,7 +188,7 @@ popd
|
||||
mkdir -p build
|
||||
pushd build
|
||||
|
||||
# compile gcc
|
||||
log_tool_name "GCC $GCC_VERSION"
|
||||
if [ ! -f $PREFIX/bin/gcc ]; then
|
||||
if [ -d gcc-$GCC_VERSION ]; then
|
||||
rm -rf gcc-$GCC_VERSION
|
||||
@ -263,7 +279,7 @@ fi
|
||||
export PATH=$PREFIX/bin:$PATH
|
||||
export LD_LIBRARY_PATH=$PREFIX/lib64
|
||||
|
||||
# compile binutils
|
||||
log_tool_name "binutils $BINUTILS_VERSION"
|
||||
if [ ! -f $PREFIX/bin/ld.gold ]; then
|
||||
if [ -d binutils-$BINUTILS_VERSION ]; then
|
||||
rm -rf binutils-$BINUTILS_VERSION
|
||||
@ -327,7 +343,7 @@ if [ ! -f $PREFIX/bin/ld.gold ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile gdb
|
||||
log_tool_name "GDB $GDB_VERSION"
|
||||
if [ ! -f $PREFIX/bin/gdb ]; then
|
||||
if [ -d gdb-$GDB_VERSION ]; then
|
||||
rm -rf gdb-$GDB_VERSION
|
||||
@ -398,13 +414,13 @@ if [ ! -f $PREFIX/bin/gdb ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install pahole
|
||||
log_tool_name "install pahole"
|
||||
if [ ! -d $PREFIX/share/pahole-gdb ]; then
|
||||
unzip ../archives/pahole-gdb-master.zip
|
||||
mv pahole-gdb-master $PREFIX/share/pahole-gdb
|
||||
fi
|
||||
|
||||
# setup system gdbinit
|
||||
log_tool_name "setup system gdbinit"
|
||||
if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then
|
||||
mkdir -p $PREFIX/etc/gdb
|
||||
cat >$PREFIX/etc/gdb/gdbinit <<EOF
|
||||
@ -430,7 +446,7 @@ end
|
||||
EOF
|
||||
fi
|
||||
|
||||
# compile cmake
|
||||
log_tool_name "cmake $CMAKE_VERSION"
|
||||
if [ ! -f $PREFIX/bin/cmake ]; then
|
||||
if [ -d cmake-$CMAKE_VERSION ]; then
|
||||
rm -rf cmake-$CMAKE_VERSION
|
||||
@ -456,7 +472,7 @@ if [ ! -f $PREFIX/bin/cmake ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile cppcheck
|
||||
log_tool_name "cppcheck $CPPCHECK_VERSION"
|
||||
if [ ! -f $PREFIX/bin/cppcheck ]; then
|
||||
if [ -d cppcheck-$CPPCHECK_VERSION ]; then
|
||||
rm -rf cppcheck-$CPPCHECK_VERSION
|
||||
@ -480,7 +496,7 @@ if [ ! -f $PREFIX/bin/cppcheck ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# compile swig
|
||||
log_tool_name "swig $SWIG_VERSION"
|
||||
if [ ! -d swig-$SWIG_VERSION/install ]; then
|
||||
if [ -d swig-$SWIG_VERSION ]; then
|
||||
rm -rf swig-$SWIG_VERSION
|
||||
@ -496,7 +512,7 @@ if [ ! -d swig-$SWIG_VERSION/install ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# compile llvm
|
||||
log_tool_name "LLVM $LLVM_VERSION"
|
||||
if [ ! -f $PREFIX/bin/clang ]; then
|
||||
if [ -d llvm-$LLVM_VERSION ]; then
|
||||
rm -rf llvm-$LLVM_VERSION
|
||||
@ -513,8 +529,19 @@ if [ ! -f $PREFIX/bin/clang ]; then
|
||||
mv compiler-rt-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/projects/compiler-rt
|
||||
tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz
|
||||
mv libunwind-$LLVM_VERSION.src/include/mach-o llvm-$LLVM_VERSION/tools/lld/include
|
||||
|
||||
# The following is required because of libc++
|
||||
tar -xvf ../archives/libcxx-$LLVM_VERSION.src.tar.xz
|
||||
mv libcxx-$LLVM_VERSION.src llvm-$LLVM_VERSION/projects/libcxx
|
||||
tar -xvf ../archives/libcxxabi-$LLVM_VERSION.src.tar.xz
|
||||
mv libcxxabi-$LLVM_VERSION.src llvm-$LLVM_VERSION/projects/libcxxabi
|
||||
# NOTE: We moved part of the libunwind in one of the previous step.
|
||||
rm -r libunwind-$LLVM_VERSION.src
|
||||
tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz
|
||||
mv libunwind-$LLVM_VERSION.src llvm-$LLVM_VERSION/projects/libunwind
|
||||
|
||||
pushd llvm-$LLVM_VERSION
|
||||
mkdir build && pushd build
|
||||
mkdir -p build && pushd build
|
||||
# activate swig
|
||||
export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH
|
||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-7&arch=amd64&ver=1%3A7.0.1%7E%2Brc2-1%7Eexp1&stamp=1541506173&raw=0
|
||||
@ -820,7 +847,11 @@ source $PREFIX/activate
|
||||
export CC=$PREFIX/bin/clang
|
||||
export CXX=$PREFIX/bin/clang++
|
||||
export CFLAGS="$CFLAGS -fPIC"
|
||||
export CXXFLAGS="$CXXFLAGS -fPIC"
|
||||
if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
|
||||
export CXXFLAGS="$CXXFLAGS -fPIC"
|
||||
else
|
||||
export CXXFLAGS="$CXXFLAGS -fPIC -stdlib=libc++"
|
||||
fi
|
||||
COMMON_CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$PREFIX
|
||||
-DCMAKE_PREFIX_PATH=$PREFIX
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
@ -834,7 +865,7 @@ COMMON_CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$PREFIX
|
||||
COMMON_CONFIGURE_FLAGS="--enable-shared=no --prefix=$PREFIX"
|
||||
COMMON_MAKE_INSTALL_FLAGS="-j$CPUS BUILD_SHARED=no PREFIX=$PREFIX install"
|
||||
|
||||
# install bzip2
|
||||
log_tool_name "bzip2 $BZIP2_VERSION"
|
||||
if [ ! -f $PREFIX/include/bzlib.h ]; then
|
||||
if [ -d bzip2-$BZIP2_VERSION ]; then
|
||||
rm -rf bzip2-$BZIP2_VERSION
|
||||
@ -845,7 +876,7 @@ if [ ! -f $PREFIX/include/bzlib.h ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# install fmt
|
||||
log_tool_name "fmt $FMT_VERSION"
|
||||
if [ ! -d $PREFIX/include/fmt ]; then
|
||||
if [ -d fmt-$FMT_VERSION ]; then
|
||||
rm -rf fmt-$FMT_VERSION
|
||||
@ -858,7 +889,7 @@ if [ ! -d $PREFIX/include/fmt ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install lz4
|
||||
log_tool_name "lz4 $LZ4_VERSION"
|
||||
if [ ! -f $PREFIX/include/lz4.h ]; then
|
||||
if [ -d lz4-$LZ4_VERSION ]; then
|
||||
rm -rf lz4-$LZ4_VERSION
|
||||
@ -869,7 +900,7 @@ if [ ! -f $PREFIX/include/lz4.h ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# install xz
|
||||
log_tool_name "xz $XZ_VERSION"
|
||||
if [ ! -f $PREFIX/include/lzma.h ]; then
|
||||
if [ -d xz-$XZ_VERSION ]; then
|
||||
rm -rf xz-$XZ_VERSION
|
||||
@ -881,7 +912,7 @@ if [ ! -f $PREFIX/include/lzma.h ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# install zlib
|
||||
log_tool_name "zlib $ZLIB_VERSION"
|
||||
if [ ! -f $PREFIX/include/zlib.h ]; then
|
||||
if [ -d zlib-$ZLIB_VERSION ]; then
|
||||
rm -rf zlib-$ZLIB_VERSION
|
||||
@ -895,7 +926,7 @@ if [ ! -f $PREFIX/include/zlib.h ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install zstd
|
||||
log_tool_name "zstd $ZSTD_VERSION"
|
||||
if [ ! -f $PREFIX/include/zstd.h ]; then
|
||||
if [ -d zstd-$ZSTD_VERSION ]; then
|
||||
rm -rf zstd-$ZSTD_VERSION
|
||||
@ -910,7 +941,8 @@ if [ ! -f $PREFIX/include/zstd.h ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
#install jemalloc
|
||||
# TODO(gitbuda): Freeze jmalloc version.
|
||||
log_tool_name "jmalloc"
|
||||
if [ ! -d $PREFIX/include/jemalloc ]; then
|
||||
if [ -d jemalloc ]; then
|
||||
rm -rf jemalloc
|
||||
@ -927,7 +959,7 @@ if [ ! -d $PREFIX/include/jemalloc ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# install boost
|
||||
log_tool_name "BOOST $BOOST_VERSION"
|
||||
if [ ! -d $PREFIX/include/boost ]; then
|
||||
if [ -d boost_$BOOST_VERSION_UNDERSCORES ]; then
|
||||
rm -rf boost_$BOOST_VERSION_UNDERSCORES
|
||||
@ -935,15 +967,24 @@ if [ ! -d $PREFIX/include/boost ]; then
|
||||
tar -xzf ../archives/boost_$BOOST_VERSION_UNDERSCORES.tar.gz
|
||||
pushd boost_$BOOST_VERSION_UNDERSCORES
|
||||
./bootstrap.sh --prefix=$PREFIX --with-toolset=clang --with-python=python3 --without-icu
|
||||
./b2 toolset=clang -j$CPUS install variant=release link=static cxxstd=20 --disable-icu \
|
||||
-sZLIB_SOURCE="$PREFIX" -sZLIB_INCLUDE="$PREFIX/include" -sZLIB_LIBPATH="$PREFIX/lib" \
|
||||
-sBZIP2_SOURCE="$PREFIX" -sBZIP2_INCLUDE="$PREFIX/include" -sBZIP2_LIBPATH="$PREFIX/lib" \
|
||||
-sLZMA_SOURCE="$PREFIX" -sLZMA_INCLUDE="$PREFIX/include" -sLZMA_LIBPATH="$PREFIX/lib" \
|
||||
-sZSTD_SOURCE="$PREFIX" -sZSTD_INCLUDE="$PREFIX/include" -sZSTD_LIBPATH="$PREFIX/lib"
|
||||
if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
|
||||
./b2 toolset=clang -j$CPUS install variant=release link=static cxxstd=20 --disable-icu \
|
||||
-sZLIB_SOURCE="$PREFIX" -sZLIB_INCLUDE="$PREFIX/include" -sZLIB_LIBPATH="$PREFIX/lib" \
|
||||
-sBZIP2_SOURCE="$PREFIX" -sBZIP2_INCLUDE="$PREFIX/include" -sBZIP2_LIBPATH="$PREFIX/lib" \
|
||||
-sLZMA_SOURCE="$PREFIX" -sLZMA_INCLUDE="$PREFIX/include" -sLZMA_LIBPATH="$PREFIX/lib" \
|
||||
-sZSTD_SOURCE="$PREFIX" -sZSTD_INCLUDE="$PREFIX/include" -sZSTD_LIBPATH="$PREFIX/lib"
|
||||
else
|
||||
./b2 toolset=clang -j$CPUS install variant=release link=static cxxstd=20 --disable-icu \
|
||||
cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++" \
|
||||
-sZLIB_SOURCE="$PREFIX" -sZLIB_INCLUDE="$PREFIX/include" -sZLIB_LIBPATH="$PREFIX/lib" \
|
||||
-sBZIP2_SOURCE="$PREFIX" -sBZIP2_INCLUDE="$PREFIX/include" -sBZIP2_LIBPATH="$PREFIX/lib" \
|
||||
-sLZMA_SOURCE="$PREFIX" -sLZMA_INCLUDE="$PREFIX/include" -sLZMA_LIBPATH="$PREFIX/lib" \
|
||||
-sZSTD_SOURCE="$PREFIX" -sZSTD_INCLUDE="$PREFIX/include" -sZSTD_LIBPATH="$PREFIX/lib"
|
||||
fi
|
||||
popd
|
||||
fi
|
||||
|
||||
# install double-conversion
|
||||
log_tool_name "double-conversion $DOUBLE_CONVERSION_VERSION"
|
||||
if [ ! -d $PREFIX/include/double-conversion ]; then
|
||||
if [ -d double-conversion-$DOUBLE_CONVERSION_VERSION ]; then
|
||||
rm -rf double-conversion-$DOUBLE_CONVERSION_VERSION
|
||||
@ -958,7 +999,8 @@ if [ ! -d $PREFIX/include/double-conversion ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install gflags
|
||||
# TODO(gitbuda): Freeze gflags version.
|
||||
log_tool_name "gflags"
|
||||
if [ ! -d $PREFIX/include/gflags ]; then
|
||||
if [ -d gflags ]; then
|
||||
rm -rf gflags
|
||||
@ -977,7 +1019,7 @@ if [ ! -d $PREFIX/include/gflags ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install libunwind
|
||||
log_tool_name "libunwind $LIBUNWIND_VERSION"
|
||||
if [ ! -f $PREFIX/include/libunwind.h ]; then
|
||||
if [ -d libunwind-$LIBUNWIND_VERSION ]; then
|
||||
rm -rf libunwind-$LIBUNWIND_VERSION
|
||||
@ -990,7 +1032,7 @@ if [ ! -f $PREFIX/include/libunwind.h ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# install glog
|
||||
log_tool_name "glog $GLOG_VERSION"
|
||||
if [ ! -d $PREFIX/include/glog ]; then
|
||||
if [ -d glog-$GLOG_VERSION ]; then
|
||||
rm -rf glog-$GLOG_VERSION
|
||||
@ -1004,7 +1046,7 @@ if [ ! -d $PREFIX/include/glog ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install libevent
|
||||
log_tool_name "libevent $LIBEVENT_VERSION"
|
||||
if [ ! -d $PREFIX/include/event2 ]; then
|
||||
if [ -d libevent-$LIBEVENT_VERSION ]; then
|
||||
rm -rf libevent-$LIBEVENT_VERSION
|
||||
@ -1023,7 +1065,7 @@ if [ ! -d $PREFIX/include/event2 ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install snappy
|
||||
log_tool_name "snappy $SNAPPY_VERSION"
|
||||
if [ ! -f $PREFIX/include/snappy.h ]; then
|
||||
if [ -d snappy-$SNAPPY_VERSION ]; then
|
||||
rm -rf snappy-$SNAPPY_VERSION
|
||||
@ -1041,7 +1083,7 @@ if [ ! -f $PREFIX/include/snappy.h ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install libsodium
|
||||
log_tool_name "libsodium $LIBSODIUM_VERSION"
|
||||
if [ ! -f $PREFIX/include/sodium.h ]; then
|
||||
if [ -d libsodium-$LIBSODIUM_VERSION ]; then
|
||||
rm -rf libsodium-$LIBSODIUM_VERSION
|
||||
@ -1053,7 +1095,7 @@ if [ ! -f $PREFIX/include/sodium.h ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# install libaio
|
||||
log_tool_name "libaio $LIBAIO_VERSION"
|
||||
if [ ! -f $PREFIX/include/libaio.h ]; then
|
||||
if [ -d libaio-$LIBAIO_VERSION ]; then
|
||||
rm -rf libaio-$LIBAIO_VERSION
|
||||
@ -1064,7 +1106,7 @@ if [ ! -f $PREFIX/include/libaio.h ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# install folly
|
||||
log_tool_name "folly $FBLIBS_VERSION"
|
||||
if [ ! -d $PREFIX/include/folly ]; then
|
||||
if [ -d folly-$FBLIBS_VERSION ]; then
|
||||
rm -rf folly-$FBLIBS_VERSION
|
||||
@ -1085,7 +1127,7 @@ if [ ! -d $PREFIX/include/folly ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install fizz
|
||||
log_tool_name "fizz $FBLIBS_VERSION"
|
||||
if [ ! -d $PREFIX/include/fizz ]; then
|
||||
if [ -d fizz-$FBLIBS_VERSION ]; then
|
||||
rm -rf fizz-$FBLIBS_VERSION
|
||||
@ -1104,7 +1146,7 @@ if [ ! -d $PREFIX/include/fizz ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install wangle
|
||||
log_tool_name "wangle FBLIBS_VERSION"
|
||||
if [ ! -d $PREFIX/include/wangle ]; then
|
||||
if [ -d wangle-$FBLIBS_VERSION ]; then
|
||||
rm -rf wangle-$FBLIBS_VERSION
|
||||
@ -1123,7 +1165,7 @@ if [ ! -d $PREFIX/include/wangle ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install proxygen
|
||||
log_tool_name "proxygen $FBLIBS_VERSION"
|
||||
if [ ! -d $PREFIX/include/proxygen ]; then
|
||||
if [ -d proxygen-$FBLIBS_VERSION ]; then
|
||||
rm -rf proxygen-$FBLIBS_VERSION
|
||||
@ -1144,7 +1186,7 @@ if [ ! -d $PREFIX/include/proxygen ]; then
|
||||
popd && popd
|
||||
fi
|
||||
|
||||
# install flex
|
||||
log_tool_name "flex $FBLIBS_VERSION"
|
||||
if [ ! -f $PREFIX/include/FlexLexer.h ]; then
|
||||
if [ -d flex-$FLEX_VERSION ]; then
|
||||
rm -rf flex-$FLEX_VERSION
|
||||
@ -1156,7 +1198,7 @@ if [ ! -f $PREFIX/include/FlexLexer.h ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
# install fbthrift
|
||||
log_tool_name "fbthrift $FBLIBS_VERSION"
|
||||
if [ ! -d $PREFIX/include/thrift ]; then
|
||||
if [ -d fbthrift-$FBLIBS_VERSION ]; then
|
||||
rm -rf fbthrift-$FBLIBS_VERSION
|
||||
@ -1166,10 +1208,15 @@ if [ ! -d $PREFIX/include/thrift ]; then
|
||||
# build is used by facebook builder
|
||||
mkdir _build
|
||||
pushd _build
|
||||
if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
|
||||
CMAKE_CXX_FLAGS="-fsized-deallocation"
|
||||
else
|
||||
CMAKE_CXX_FLAGS="-fsized-deallocation -stdlib=libc++"
|
||||
fi
|
||||
cmake .. $COMMON_CMAKE_FLAGS \
|
||||
-Denable_tests=OFF \
|
||||
-DGFLAGS_NOTHREADS=OFF \
|
||||
-DCMAKE_CXX_FLAGS=-fsized-deallocation
|
||||
-DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS"
|
||||
make -j$CPUS install
|
||||
popd
|
||||
fi
|
||||
@ -1192,7 +1239,12 @@ if [ ! -f $NAME-binaries-$DISTRO.tar.gz ]; then
|
||||
DISTRO_FULL_NAME="$DISTRO_FULL_NAME-amd64"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
|
||||
# Pass because infra scripts assume there is not C++ standard lib in the name.
|
||||
echo "NOTE: Not adding anything to the archive name that GCC C++ standard lib is used."
|
||||
else
|
||||
DISTRO_FULL_NAME="$DISTRO_FULL_NAME-libc++"
|
||||
fi
|
||||
tar --owner=root --group=root -cpvzf $NAME-binaries-$DISTRO_FULL_NAME.tar.gz -C /opt $NAME
|
||||
fi
|
||||
|
||||
|
@ -36,7 +36,7 @@ ADDITIONAL USE GRANT: You may use the Licensed Work in accordance with the
|
||||
3. using the Licensed Work to create a work or solution
|
||||
which competes (or might reasonably be expected to
|
||||
compete) with the Licensed Work.
|
||||
CHANGE DATE: 2026-07-10
|
||||
CHANGE DATE: 2026-07-11
|
||||
CHANGE LICENSE: Apache License, Version 2.0
|
||||
|
||||
For information about alternative licensing arrangements, please visit: https://memgraph.com/legal.
|
||||
|
@ -2,8 +2,8 @@ MEMGRAPH
|
||||
ENTERPRISE LICENCE AGREEMENT
|
||||
|
||||
|
||||
Memgraph Limited is registered in England under registration 10195084 and has its registered office at Suite 4,
|
||||
Ironstone House, Ironstone Way, Brixworth, Northampton, NN6 9UD (“Memgraph”).
|
||||
Memgraph Limited is registered in England under registration 10195084 and has its registered office at 90a High Street,
|
||||
Hertfordshire, Berkhamsted, HP4 2BL United Kingdom ("Memgraph").
|
||||
|
||||
|
||||
Memgraph agrees to license and/or grant you (the “Customer”) access to the Software ( as defined below) and provide
|
||||
|
@ -1,4 +1,11 @@
|
||||
# mgp
|
||||
|
||||
PyPi package used for type hinting when creating MAGE modules. The get started
|
||||
using MAGE repository checkout the repository here: https://github.com/memgraph/mage.
|
||||
PyPi package used for type hinting when creating query modules. Repository of already available query modules is called [MAGE](https://github.com/memgraph/mage).
|
||||
|
||||
## 🎬 Get started
|
||||
|
||||
To learn more, head over to the [docs for the query modules Python API](https://memgraph.com/docs/memgraph/reference-guide/query-modules/api/python-api). To get started with query modules, check out the [how-to guide](https://memgraph.com/docs/memgraph/how-to-guides/query-modules) on Memgraph docs.
|
||||
|
||||
## 🔢 Versioning
|
||||
|
||||
- mgp v1.1 is compatible with Memgraph >= 2.4.0
|
||||
|
@ -257,3 +257,11 @@ class _MODULE:
|
||||
@staticmethod
|
||||
def add_function(wrapper):
|
||||
pass
|
||||
|
||||
|
||||
class SOURCE_TYPE_KAFKA:
|
||||
pass
|
||||
|
||||
|
||||
class SOURCE_TYPE_PULSAR:
|
||||
pass
|
||||
|
@ -1,13 +1,13 @@
|
||||
[tool.poetry]
|
||||
name = "mgp"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
description = "Memgraph's module for developing MAGE modules. Used only for type hinting!"
|
||||
authors = [
|
||||
"MasterMedo <mislav.vuletic@gmail.com>",
|
||||
"jbajic <jure.bajic@memgraph.io>",
|
||||
"katarinasupe <katarina.supe@memgraph.io>",
|
||||
"jbajic <jure.bajic@memgraph.io>",
|
||||
"antejavor <ante.javor@memgraph.io>",
|
||||
"antaljanosbenjamin <benjamin.antal@memgraph.io>",
|
||||
"MasterMedo <mislav.vuletic@gmail.com>",
|
||||
]
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
|
@ -15,10 +15,11 @@ add_subdirectory(query)
|
||||
add_subdirectory(glue)
|
||||
add_subdirectory(slk)
|
||||
add_subdirectory(rpc)
|
||||
add_subdirectory(license)
|
||||
add_subdirectory(auth)
|
||||
|
||||
if (MG_ENTERPRISE)
|
||||
add_subdirectory(audit)
|
||||
if(MG_ENTERPRISE)
|
||||
add_subdirectory(audit)
|
||||
endif()
|
||||
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
||||
@ -36,68 +37,76 @@ set(mg_single_node_v2_sources
|
||||
)
|
||||
|
||||
set(mg_single_node_v2_libs stdc++fs Threads::Threads
|
||||
telemetry_lib mg-query mg-communication mg-memory mg-utils mg-auth mg-license mg-settings mg-glue)
|
||||
if (MG_ENTERPRISE)
|
||||
# These are enterprise subsystems
|
||||
set(mg_single_node_v2_libs ${mg_single_node_v2_libs} mg-audit)
|
||||
mg-telemetry mg-query mg-communication mg-memory mg-utils mg-auth mg-license mg-settings mg-glue)
|
||||
|
||||
if(MG_ENTERPRISE)
|
||||
# These are enterprise subsystems
|
||||
set(mg_single_node_v2_libs ${mg_single_node_v2_libs} mg-audit)
|
||||
endif()
|
||||
|
||||
# memgraph main executable
|
||||
add_executable(memgraph ${mg_single_node_v2_sources})
|
||||
target_include_directories(memgraph PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
||||
target_link_libraries(memgraph ${mg_single_node_v2_libs})
|
||||
|
||||
# NOTE: `include/mg_procedure.syms` describes a pattern match for symbols which
|
||||
# should be dynamically exported, so that `dlopen` can correctly link the
|
||||
# symbols in custom procedure module libraries.
|
||||
target_link_libraries(memgraph "-Wl,--dynamic-list=${CMAKE_SOURCE_DIR}/include/mg_procedure.syms")
|
||||
set_target_properties(memgraph PROPERTIES
|
||||
# Set the executable output name to include version information.
|
||||
OUTPUT_NAME "memgraph-${MEMGRAPH_VERSION}_${CMAKE_BUILD_TYPE}"
|
||||
# Output the executable in main binary dir.
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
# Set the executable output name to include version information.
|
||||
OUTPUT_NAME "memgraph-${MEMGRAPH_VERSION}_${CMAKE_BUILD_TYPE}"
|
||||
|
||||
# Output the executable in main binary dir.
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
# Create symlink to the built executable.
|
||||
add_custom_command(TARGET memgraph POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:memgraph> ${CMAKE_BINARY_DIR}/memgraph
|
||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/memgraph
|
||||
COMMENT "Creating symlink to memgraph executable")
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:memgraph> ${CMAKE_BINARY_DIR}/memgraph
|
||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/memgraph
|
||||
COMMENT "Creating symlink to memgraph executable")
|
||||
|
||||
# Emulate the installed python_support, by creating a symlink
|
||||
add_custom_command(TARGET memgraph POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/python_support
|
||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/python_support
|
||||
COMMENT "Creating symlink for python_support")
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/python_support
|
||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/python_support
|
||||
COMMENT "Creating symlink for python_support")
|
||||
|
||||
# Strip the executable in release build.
|
||||
if (lower_build_type STREQUAL "release")
|
||||
add_custom_command(TARGET memgraph POST_BUILD
|
||||
COMMAND strip -s $<TARGET_FILE:memgraph>
|
||||
COMMENT "Stripping symbols and sections from memgraph")
|
||||
if(lower_build_type STREQUAL "release")
|
||||
add_custom_command(TARGET memgraph POST_BUILD
|
||||
COMMAND strip -s $<TARGET_FILE:memgraph>
|
||||
COMMENT "Stripping symbols and sections from memgraph")
|
||||
endif()
|
||||
|
||||
# Generate the configuration file.
|
||||
add_custom_command(TARGET memgraph POST_BUILD
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/config/generate.py
|
||||
${CMAKE_BINARY_DIR}/memgraph
|
||||
${CMAKE_BINARY_DIR}/config/memgraph.conf
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/config/generate.py
|
||||
${CMAKE_SOURCE_DIR}/config/flags.yaml
|
||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/config/memgraph.conf
|
||||
COMMENT "Generating memgraph configuration file")
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/config/generate.py
|
||||
${CMAKE_BINARY_DIR}/memgraph
|
||||
${CMAKE_BINARY_DIR}/config/memgraph.conf
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/config/generate.py
|
||||
${CMAKE_SOURCE_DIR}/config/flags.yaml
|
||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/config/memgraph.conf
|
||||
COMMENT "Generating memgraph configuration file")
|
||||
|
||||
# Everything here is under "memgraph" install component.
|
||||
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "memgraph")
|
||||
|
||||
# TODO: Default directory permissions to 755
|
||||
# NOTE: This is added in CMake 3.11, so enable it then
|
||||
#set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
|
||||
# OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ WORLD_READ)
|
||||
# set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
|
||||
# OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ WORLD_READ)
|
||||
|
||||
# Install and rename executable to just 'memgraph' Since we have to rename,
|
||||
# we cannot use the recommended `install(TARGETS ...)`.
|
||||
install(PROGRAMS $<TARGET_FILE:memgraph>
|
||||
DESTINATION lib/memgraph RENAME memgraph)
|
||||
|
||||
# Install Python source for supporting our embedded Python.
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.py
|
||||
DESTINATION lib/memgraph/python_support)
|
||||
|
||||
# Install the includes file for writing custom procedures in C and C++>
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/include/mg_procedure.h
|
||||
DESTINATION include/memgraph)
|
||||
@ -107,9 +116,11 @@ install(FILES ${CMAKE_SOURCE_DIR}/include/mg_exceptions.hpp
|
||||
DESTINATION include/memgraph)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.hpp
|
||||
DESTINATION include/memgraph)
|
||||
|
||||
# Install the config file (must use absolute path).
|
||||
install(FILES ${CMAKE_BINARY_DIR}/config/memgraph.conf
|
||||
DESTINATION /etc/memgraph RENAME memgraph.conf)
|
||||
|
||||
# Install logrotate configuration (must use absolute path).
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate.conf
|
||||
DESTINATION /etc/logrotate.d RENAME memgraph)
|
||||
@ -125,15 +136,14 @@ install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}/var/log/memgraph
|
||||
# ----------------------------------------------------------------------------
|
||||
# Memgraph CSV Import Tool Executable
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
add_executable(mg_import_csv mg_import_csv.cpp)
|
||||
target_link_libraries(mg_import_csv mg-storage-v2)
|
||||
|
||||
# Strip the executable in release build.
|
||||
if (lower_build_type STREQUAL "release")
|
||||
add_custom_command(TARGET mg_import_csv POST_BUILD
|
||||
COMMAND strip -s mg_import_csv
|
||||
COMMENT "Stripping symbols and sections from mg_import_csv")
|
||||
if(lower_build_type STREQUAL "release")
|
||||
add_custom_command(TARGET mg_import_csv POST_BUILD
|
||||
COMMAND strip -s mg_import_csv
|
||||
COMMENT "Stripping symbols and sections from mg_import_csv")
|
||||
endif()
|
||||
|
||||
install(TARGETS mg_import_csv RUNTIME DESTINATION bin)
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "auth/exceptions.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "utils/flag_validation.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/message.hpp"
|
||||
#include "utils/settings.hpp"
|
||||
@ -68,10 +68,9 @@ Auth::Auth(const std::string &storage_directory) : storage_(storage_directory),
|
||||
|
||||
std::optional<User> Auth::Authenticate(const std::string &username, const std::string &password) {
|
||||
if (module_.IsUsed()) {
|
||||
const auto license_check_result = utils::license::global_license_checker.IsValidLicense(utils::global_settings);
|
||||
const auto license_check_result = license::global_license_checker.IsEnterpriseValid(utils::global_settings);
|
||||
if (license_check_result.HasError()) {
|
||||
spdlog::warn(
|
||||
utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "authentication modules"));
|
||||
spdlog::warn(license::LicenseCheckErrorToString(license_check_result.GetError(), "authentication modules"));
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
|
||||
#include "auth/crypto.hpp"
|
||||
#include "auth/exceptions.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "utils/cast.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/settings.hpp"
|
||||
#include "utils/string.hpp"
|
||||
@ -242,7 +242,7 @@ FineGrainedAccessPermissions::FineGrainedAccessPermissions(const std::unordered_
|
||||
|
||||
PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission,
|
||||
const FineGrainedPermission fine_grained_permission) const {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return PermissionLevel::GRANT;
|
||||
}
|
||||
const auto concrete_permission = std::invoke([&]() -> uint64_t {
|
||||
@ -281,7 +281,7 @@ void FineGrainedAccessPermissions::Revoke(const std::string &permission) {
|
||||
}
|
||||
|
||||
nlohmann::json FineGrainedAccessPermissions::Serialize() const {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return {};
|
||||
}
|
||||
nlohmann::json data = nlohmann::json::object();
|
||||
@ -294,7 +294,7 @@ FineGrainedAccessPermissions FineGrainedAccessPermissions::Deserialize(const nlo
|
||||
if (!data.is_object()) {
|
||||
throw AuthException("Couldn't load permissions data!");
|
||||
}
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return FineGrainedAccessPermissions{};
|
||||
}
|
||||
std::optional<uint64_t> global_permission;
|
||||
@ -347,7 +347,7 @@ const FineGrainedAccessPermissions &FineGrainedAccessHandler::edge_type_permissi
|
||||
FineGrainedAccessPermissions &FineGrainedAccessHandler::edge_type_permissions() { return edge_type_permissions_; }
|
||||
|
||||
nlohmann::json FineGrainedAccessHandler::Serialize() const {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return {};
|
||||
}
|
||||
nlohmann::json data = nlohmann::json::object();
|
||||
@ -363,7 +363,7 @@ FineGrainedAccessHandler FineGrainedAccessHandler::Deserialize(const nlohmann::j
|
||||
if (!data["label_permissions"].is_object() || !data["edge_type_permissions"].is_object()) {
|
||||
throw AuthException("Couldn't load label_permissions or edge_type_permissions data!");
|
||||
}
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return FineGrainedAccessHandler{};
|
||||
}
|
||||
auto label_permissions = FineGrainedAccessPermissions::Deserialize(data["label_permissions"]);
|
||||
@ -414,7 +414,7 @@ nlohmann::json Role::Serialize() const {
|
||||
data["rolename"] = rolename_;
|
||||
data["permissions"] = permissions_.Serialize();
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize();
|
||||
} else {
|
||||
data["fine_grained_access_handler"] = {};
|
||||
@ -432,7 +432,7 @@ Role Role::Deserialize(const nlohmann::json &data) {
|
||||
}
|
||||
auto permissions = Permissions::Deserialize(data["permissions"]);
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
if (!data["fine_grained_access_handler"].is_object()) {
|
||||
throw AuthException("Couldn't load user data!");
|
||||
}
|
||||
@ -445,7 +445,7 @@ Role Role::Deserialize(const nlohmann::json &data) {
|
||||
|
||||
bool operator==(const Role &first, const Role &second) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return first.rolename_ == second.rolename_ && first.permissions_ == second.permissions_ &&
|
||||
first.fine_grained_access_handler_ == second.fine_grained_access_handler_;
|
||||
}
|
||||
@ -483,13 +483,13 @@ void User::UpdatePassword(const std::optional<std::string> &password) {
|
||||
}
|
||||
|
||||
if (FLAGS_auth_password_strength_regex != default_password_regex) {
|
||||
if (const auto license_check_result = utils::license::global_license_checker.IsValidLicense(utils::global_settings);
|
||||
if (const auto license_check_result = license::global_license_checker.IsEnterpriseValid(utils::global_settings);
|
||||
license_check_result.HasError()) {
|
||||
throw AuthException(
|
||||
"Custom password regex is a Memgraph Enterprise feature. Please set the config "
|
||||
"(\"--auth-password-strength-regex\") to its default value (\"{}\") or remove the flag.\n{}",
|
||||
default_password_regex,
|
||||
utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "password regex"));
|
||||
license::LicenseCheckErrorToString(license_check_result.GetError(), "password regex"));
|
||||
}
|
||||
}
|
||||
std::regex re(FLAGS_auth_password_strength_regex);
|
||||
@ -517,7 +517,7 @@ Permissions User::GetPermissions() const {
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return FineGrainedAccessPermissions{};
|
||||
}
|
||||
|
||||
@ -530,7 +530,7 @@ FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const
|
||||
}
|
||||
|
||||
FineGrainedAccessPermissions User::GetFineGrainedAccessEdgeTypePermissions() const {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return FineGrainedAccessPermissions{};
|
||||
}
|
||||
if (role_) {
|
||||
@ -563,7 +563,7 @@ nlohmann::json User::Serialize() const {
|
||||
data["password_hash"] = password_hash_;
|
||||
data["permissions"] = permissions_.Serialize();
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize();
|
||||
} else {
|
||||
data["fine_grained_access_handler"] = {};
|
||||
@ -582,7 +582,7 @@ User User::Deserialize(const nlohmann::json &data) {
|
||||
}
|
||||
auto permissions = Permissions::Deserialize(data["permissions"]);
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
if (!data["fine_grained_access_handler"].is_object()) {
|
||||
throw AuthException("Couldn't load user data!");
|
||||
}
|
||||
@ -595,7 +595,7 @@ User User::Deserialize(const nlohmann::json &data) {
|
||||
|
||||
bool operator==(const User &first, const User &second) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return first.username_ == second.username_ && first.password_hash_ == second.password_hash_ &&
|
||||
first.permissions_ == second.permissions_ && first.role_ == second.role_ &&
|
||||
first.fine_grained_access_handler_ == second.fine_grained_access_handler_;
|
||||
|
@ -14,8 +14,8 @@
|
||||
#include "auth/auth.hpp"
|
||||
#include "auth/models.hpp"
|
||||
#include "glue/auth.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
@ -23,7 +23,7 @@ namespace {
|
||||
bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba,
|
||||
const std::vector<memgraph::storage::LabelId> &labels,
|
||||
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return true;
|
||||
}
|
||||
return std::all_of(labels.begin(), labels.end(), [dba, &user, fine_grained_privilege](const auto &label) {
|
||||
@ -35,7 +35,7 @@ bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::qu
|
||||
|
||||
bool IsUserAuthorizedGloballyLabels(const memgraph::auth::User &user,
|
||||
const memgraph::auth::FineGrainedPermission fine_grained_permission) {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return true;
|
||||
}
|
||||
return user.GetFineGrainedAccessLabelPermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) ==
|
||||
@ -44,7 +44,7 @@ bool IsUserAuthorizedGloballyLabels(const memgraph::auth::User &user,
|
||||
|
||||
bool IsUserAuthorizedGloballyEdges(const memgraph::auth::User &user,
|
||||
const memgraph::auth::FineGrainedPermission fine_grained_permission) {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return true;
|
||||
}
|
||||
return user.GetFineGrainedAccessEdgeTypePermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) ==
|
||||
@ -54,7 +54,7 @@ bool IsUserAuthorizedGloballyEdges(const memgraph::auth::User &user,
|
||||
bool IsUserAuthorizedEdgeType(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba,
|
||||
const memgraph::storage::EdgeTypeId &edgeType,
|
||||
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return true;
|
||||
}
|
||||
return user.GetFineGrainedAccessEdgeTypePermissions().Has(
|
||||
@ -87,7 +87,7 @@ bool AuthChecker::IsUserAuthorized(const std::optional<std::string> &username,
|
||||
#ifdef MG_ENTERPRISE
|
||||
std::unique_ptr<memgraph::query::FineGrainedAuthChecker> AuthChecker::GetFineGrainedAuthChecker(
|
||||
const std::string &username, const memgraph::query::DbAccessor *dba) const {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return {};
|
||||
}
|
||||
try {
|
||||
@ -154,7 +154,7 @@ bool FineGrainedAuthChecker::Has(const memgraph::storage::EdgeTypeId &edge_type,
|
||||
|
||||
bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices(
|
||||
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return true;
|
||||
}
|
||||
return IsUserAuthorizedGloballyLabels(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege));
|
||||
@ -162,7 +162,7 @@ bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices(
|
||||
|
||||
bool FineGrainedAuthChecker::HasGlobalPrivilegeOnEdges(
|
||||
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return true;
|
||||
}
|
||||
return IsUserAuthorizedGloballyEdges(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege));
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "auth/models.hpp"
|
||||
#include "glue/auth.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "license/license.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -125,7 +125,7 @@ std::vector<FineGrainedPermissionForPrivilegeResult> GetFineGrainedPermissionFor
|
||||
const memgraph::auth::FineGrainedAccessPermissions &permissions, const std::string &permission_type,
|
||||
const std::string &user_or_role) {
|
||||
std::vector<FineGrainedPermissionForPrivilegeResult> fine_grained_permissions;
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return fine_grained_permissions;
|
||||
}
|
||||
const auto global_permission = permissions.GetGlobalPermission();
|
||||
@ -166,7 +166,7 @@ std::vector<FineGrainedPermissionForPrivilegeResult> GetFineGrainedPermissionFor
|
||||
std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivilegesResult(
|
||||
const std::vector<FineGrainedPermissionForPrivilegeResult> &privileges) {
|
||||
std::vector<std::vector<memgraph::query::TypedValue>> grants;
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return {};
|
||||
}
|
||||
grants.reserve(privileges.size());
|
||||
@ -182,7 +182,7 @@ std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivil
|
||||
|
||||
std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivileges(
|
||||
const std::optional<memgraph::auth::User> &user) {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return {};
|
||||
}
|
||||
const auto &label_permissions = user->GetFineGrainedAccessLabelPermissions();
|
||||
@ -201,7 +201,7 @@ std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivile
|
||||
|
||||
std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedRolePrivileges(
|
||||
const std::optional<memgraph::auth::Role> &role) {
|
||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
return {};
|
||||
}
|
||||
const auto &label_permissions = role->GetFineGrainedAccessLabelPermissions();
|
||||
@ -231,13 +231,13 @@ AuthQueryHandler::AuthQueryHandler(
|
||||
bool AuthQueryHandler::CreateUser(const std::string &username, const std::optional<std::string> &password) {
|
||||
if (name_regex_string_ != kDefaultUserRoleRegex) {
|
||||
if (const auto license_check_result =
|
||||
memgraph::utils::license::global_license_checker.IsValidLicense(memgraph::utils::global_settings);
|
||||
memgraph::license::global_license_checker.IsEnterpriseValid(memgraph::utils::global_settings);
|
||||
license_check_result.HasError()) {
|
||||
throw memgraph::auth::AuthException(
|
||||
"Custom user/role regex is a Memgraph Enterprise feature. Please set the config "
|
||||
"(\"--auth-user-or-role-name-regex\") to its default value (\"{}\") or remove the flag.\n{}",
|
||||
kDefaultUserRoleRegex,
|
||||
memgraph::utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "user/role regex"));
|
||||
memgraph::license::LicenseCheckErrorToString(license_check_result.GetError(), "user/role regex"));
|
||||
}
|
||||
}
|
||||
if (!std::regex_match(username, name_regex_)) {
|
||||
@ -473,20 +473,20 @@ std::vector<std::vector<memgraph::query::TypedValue>> AuthQueryHandler::GetPrivi
|
||||
if (user) {
|
||||
grants = ShowUserPrivileges(user);
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
fine_grained_grants = ShowFineGrainedUserPrivileges(user);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
grants = ShowRolePrivileges(role);
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
fine_grained_grants = ShowFineGrainedRolePrivileges(role);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
grants.insert(grants.end(), fine_grained_grants.begin(), fine_grained_grants.end());
|
||||
}
|
||||
#endif
|
||||
@ -627,7 +627,7 @@ void AuthQueryHandler::EditPermissions(
|
||||
edit_permissions_fun(user->permissions(), permission);
|
||||
}
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
for (const auto &label_privilege_collection : label_privileges) {
|
||||
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(),
|
||||
label_privilege_collection);
|
||||
@ -644,7 +644,7 @@ void AuthQueryHandler::EditPermissions(
|
||||
edit_permissions_fun(role->permissions(), permission);
|
||||
}
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
for (const auto &label_privilege : label_privileges) {
|
||||
edit_fine_grained_permissions_fun(role->fine_grained_access_handler().label_permissions(), label_privilege);
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
|
||||
#include "auth/auth.hpp"
|
||||
#include "glue/auth.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace memgraph::glue {
|
||||
|
6
src/license/CMakeLists.txt
Normal file
6
src/license/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
set(license_src_files
|
||||
license_sender.cpp
|
||||
license.cpp)
|
||||
add_library(mg-license STATIC ${license_src_files})
|
||||
|
||||
target_link_libraries(mg-license mg-settings mg-utils mg-requests spdlog::spdlog)
|
@ -9,17 +9,19 @@
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include "utils/license.hpp"
|
||||
#include "license/license.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <charconv>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "slk/serialization.hpp"
|
||||
#include "utils/base64.hpp"
|
||||
#include "utils/cast.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/memory_tracker.hpp"
|
||||
@ -27,7 +29,7 @@
|
||||
#include "utils/spin_lock.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
|
||||
namespace memgraph::utils::license {
|
||||
namespace memgraph::license {
|
||||
|
||||
namespace {
|
||||
inline constexpr std::string_view license_key_prefix = "mglk-";
|
||||
@ -69,6 +71,17 @@ LicenseCheckResult IsValidLicenseInternal(const License &license, const std::str
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string LicenseTypeToString(const LicenseType license_type) {
|
||||
switch (license_type) {
|
||||
case LicenseType::ENTERPRISE: {
|
||||
return "enterprise";
|
||||
}
|
||||
case LicenseType::OEM: {
|
||||
return "oem";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterLicenseSettings(LicenseChecker &license_checker, utils::Settings &settings) {
|
||||
settings.RegisterSetting(std::string{kEnterpriseLicenseSettingKey}, "",
|
||||
[&] { license_checker.RevalidateLicense(settings); });
|
||||
@ -81,7 +94,7 @@ LicenseChecker global_license_checker;
|
||||
|
||||
LicenseChecker::~LicenseChecker() { scheduler_.Stop(); }
|
||||
|
||||
std::pair<std::string, std::string> LicenseChecker::GetLicenseInfo(const utils::Settings &settings) const {
|
||||
std::pair<std::string, std::string> LicenseChecker::ExtractLicenseInfo(const utils::Settings &settings) const {
|
||||
if (license_info_override_) {
|
||||
spdlog::warn("Ignoring license info stored in the settings because a different source was specified.");
|
||||
return *license_info_override_;
|
||||
@ -96,7 +109,7 @@ std::pair<std::string, std::string> LicenseChecker::GetLicenseInfo(const utils::
|
||||
}
|
||||
|
||||
void LicenseChecker::RevalidateLicense(const utils::Settings &settings) {
|
||||
const auto license_info = GetLicenseInfo(settings);
|
||||
const auto license_info = ExtractLicenseInfo(settings);
|
||||
RevalidateLicense(license_info.first, license_info.second);
|
||||
}
|
||||
|
||||
@ -117,18 +130,7 @@ void LicenseChecker::RevalidateLicense(const std::string &license_key, const std
|
||||
return;
|
||||
}
|
||||
|
||||
struct PreviousLicenseInfo {
|
||||
PreviousLicenseInfo(std::string license_key, std::string organization_name)
|
||||
: license_key(std::move(license_key)), organization_name(std::move(organization_name)) {}
|
||||
|
||||
std::string license_key;
|
||||
std::string organization_name;
|
||||
bool is_valid{false};
|
||||
};
|
||||
|
||||
static utils::Synchronized<std::optional<PreviousLicenseInfo>, utils::SpinLock> previous_license_info;
|
||||
|
||||
auto locked_previous_license_info_ptr = previous_license_info.Lock();
|
||||
auto locked_previous_license_info_ptr = previous_license_info_.Lock();
|
||||
auto &locked_previous_license_info = *locked_previous_license_info_ptr;
|
||||
const bool same_license_info = locked_previous_license_info &&
|
||||
locked_previous_license_info->license_key == license_key &&
|
||||
@ -140,7 +142,7 @@ void LicenseChecker::RevalidateLicense(const std::string &license_key, const std
|
||||
|
||||
locked_previous_license_info.emplace(license_key, organization_name);
|
||||
|
||||
const auto maybe_license = GetLicense(locked_previous_license_info->license_key);
|
||||
auto maybe_license = GetLicense(locked_previous_license_info->license_key);
|
||||
if (!maybe_license) {
|
||||
spdlog::warn(LicenseCheckErrorToString(LicenseCheckError::INVALID_LICENSE_KEY_STRING, "Enterprise features"));
|
||||
is_valid_.store(false, std::memory_order_relaxed);
|
||||
@ -156,22 +158,30 @@ void LicenseChecker::RevalidateLicense(const std::string &license_key, const std
|
||||
spdlog::warn(LicenseCheckErrorToString(license_check_result.GetError(), "Enterprise features"));
|
||||
is_valid_.store(false, std::memory_order_relaxed);
|
||||
locked_previous_license_info->is_valid = false;
|
||||
license_type_ = maybe_license->type;
|
||||
set_memory_limit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!same_license_info) {
|
||||
spdlog::info("All Enterprise features are active.");
|
||||
license_type_ = maybe_license->type;
|
||||
if (license_type_ == LicenseType::ENTERPRISE) {
|
||||
spdlog::info("Enterprise license is active.");
|
||||
} else {
|
||||
spdlog::info("OEM license is active.");
|
||||
}
|
||||
is_valid_.store(true, std::memory_order_relaxed);
|
||||
locked_previous_license_info->is_valid = true;
|
||||
set_memory_limit(maybe_license->memory_limit);
|
||||
locked_previous_license_info->license = std::move(*maybe_license);
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseChecker::EnableTesting() {
|
||||
void LicenseChecker::EnableTesting(const LicenseType license_type) {
|
||||
enterprise_enabled_ = true;
|
||||
is_valid_.store(true, std::memory_order_relaxed);
|
||||
spdlog::info("All Enterprise features are activated for testing.");
|
||||
license_type_ = license_type;
|
||||
spdlog::info("The license type {} is set for testing.", LicenseTypeToString(license_type));
|
||||
}
|
||||
|
||||
void LicenseChecker::CheckEnvLicense() {
|
||||
@ -216,20 +226,26 @@ std::string LicenseCheckErrorToString(LicenseCheckError error, const std::string
|
||||
"following query:\n"
|
||||
"SET DATABASE SETTING \"enterprise.license\" TO \"your-license-key\"",
|
||||
feature);
|
||||
case LicenseCheckError::NOT_ENTERPRISE_LICENSE:
|
||||
return fmt::format("Your license has an invalid type. To use {} you need to have an enterprise license. \n",
|
||||
feature);
|
||||
}
|
||||
}
|
||||
|
||||
LicenseCheckResult LicenseChecker::IsValidLicense(const utils::Settings &settings) const {
|
||||
LicenseCheckResult LicenseChecker::IsEnterpriseValid(const utils::Settings &settings) const {
|
||||
if (enterprise_enabled_) [[unlikely]] {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto license_info = GetLicenseInfo(settings);
|
||||
const auto license_info = ExtractLicenseInfo(settings);
|
||||
|
||||
const auto maybe_license = GetLicense(license_info.first);
|
||||
if (!maybe_license) {
|
||||
return LicenseCheckError::INVALID_LICENSE_KEY_STRING;
|
||||
}
|
||||
if (maybe_license->type != LicenseType::ENTERPRISE) {
|
||||
return LicenseCheckError::NOT_ENTERPRISE_LICENSE;
|
||||
}
|
||||
|
||||
return IsValidLicenseInternal(*maybe_license, license_info.second);
|
||||
}
|
||||
@ -239,7 +255,13 @@ void LicenseChecker::StartBackgroundLicenseChecker(const utils::Settings &settin
|
||||
scheduler_.Run("licensechecker", std::chrono::minutes{5}, [&, this] { RevalidateLicense(settings); });
|
||||
}
|
||||
|
||||
bool LicenseChecker::IsValidLicenseFast() const { return is_valid_.load(std::memory_order_relaxed); }
|
||||
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &LicenseChecker::GetLicenseInfo() {
|
||||
return previous_license_info_;
|
||||
}
|
||||
|
||||
bool LicenseChecker::IsEnterpriseValidFast() const {
|
||||
return license_type_ == LicenseType::ENTERPRISE && is_valid_.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
std::string Encode(const License &license) {
|
||||
std::vector<uint8_t> buffer;
|
||||
@ -252,9 +274,10 @@ std::string Encode(const License &license) {
|
||||
slk::Save(license.organization_name, &builder);
|
||||
slk::Save(license.valid_until, &builder);
|
||||
slk::Save(license.memory_limit, &builder);
|
||||
slk::Save(utils::UnderlyingCast(license.type), &builder);
|
||||
builder.Finalize();
|
||||
|
||||
return std::string{license_key_prefix} + base64_encode(buffer.data(), buffer.size());
|
||||
return std::string{license_key_prefix} + utils::base64_encode(buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
std::optional<License> Decode(std::string_view license_key) {
|
||||
@ -266,7 +289,7 @@ std::optional<License> Decode(std::string_view license_key) {
|
||||
|
||||
const auto decoded = std::invoke([license_key]() -> std::optional<std::string> {
|
||||
try {
|
||||
return base64_decode(license_key);
|
||||
return utils::base64_decode(license_key);
|
||||
} catch (const std::runtime_error & /*exception*/) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@ -284,10 +307,12 @@ std::optional<License> Decode(std::string_view license_key) {
|
||||
slk::Load(&valid_until, &reader);
|
||||
int64_t memory_limit{0};
|
||||
slk::Load(&memory_limit, &reader);
|
||||
return License{.organization_name = organization_name, .valid_until = valid_until, .memory_limit = memory_limit};
|
||||
std::underlying_type_t<LicenseType> license_type{0};
|
||||
slk::Load(&license_type, &reader);
|
||||
return {License{organization_name, valid_until, memory_limit, LicenseType(license_type)}};
|
||||
} catch (const slk::SlkReaderException &e) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace memgraph::utils::license
|
||||
} // namespace memgraph::license
|
@ -12,26 +12,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "utils/result.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
#include "utils/settings.hpp"
|
||||
#include "utils/spin_lock.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
|
||||
namespace memgraph::utils::license {
|
||||
namespace memgraph::license {
|
||||
|
||||
enum class LicenseType : uint8_t { ENTERPRISE, OEM };
|
||||
|
||||
std::string LicenseTypeToString(LicenseType license_type);
|
||||
|
||||
struct License {
|
||||
License() = default;
|
||||
|
||||
License(std::string organization_name, int64_t valid_until, int64_t memory_limit, LicenseType license_type)
|
||||
: organization_name{std::move(organization_name)},
|
||||
valid_until{valid_until},
|
||||
memory_limit{memory_limit},
|
||||
type{license_type} {}
|
||||
|
||||
std::string organization_name;
|
||||
int64_t valid_until;
|
||||
int64_t memory_limit;
|
||||
LicenseType type;
|
||||
|
||||
bool operator==(const License &) const = default;
|
||||
};
|
||||
|
||||
struct LicenseInfo {
|
||||
LicenseInfo(std::string license_key, std::string organization_name)
|
||||
: license_key(std::move(license_key)), organization_name{std::move(organization_name)} {}
|
||||
|
||||
std::string license_key;
|
||||
std::string organization_name;
|
||||
bool is_valid{false};
|
||||
License license;
|
||||
};
|
||||
|
||||
inline constexpr std::string_view kEnterpriseLicenseSettingKey = "enterprise.license";
|
||||
inline constexpr std::string_view kOrganizationNameSettingKey = "organization.name";
|
||||
|
||||
enum class LicenseCheckError : uint8_t { INVALID_LICENSE_KEY_STRING, INVALID_ORGANIZATION_NAME, EXPIRED_LICENSE };
|
||||
enum class LicenseCheckError : uint8_t {
|
||||
INVALID_LICENSE_KEY_STRING,
|
||||
INVALID_ORGANIZATION_NAME,
|
||||
EXPIRED_LICENSE,
|
||||
NOT_ENTERPRISE_LICENSE
|
||||
};
|
||||
|
||||
std::string LicenseCheckErrorToString(LicenseCheckError error, std::string_view feature);
|
||||
|
||||
@ -49,19 +80,25 @@ struct LicenseChecker {
|
||||
|
||||
void CheckEnvLicense();
|
||||
void SetLicenseInfoOverride(std::string license_key, std::string organization_name);
|
||||
void EnableTesting();
|
||||
LicenseCheckResult IsValidLicense(const utils::Settings &settings) const;
|
||||
bool IsValidLicenseFast() const;
|
||||
void EnableTesting(LicenseType license_type = LicenseType::ENTERPRISE);
|
||||
// Checks if license is valid and if enterprise is enabled
|
||||
LicenseCheckResult IsEnterpriseValid(const utils::Settings &settings) const;
|
||||
bool IsEnterpriseValidFast() const;
|
||||
|
||||
void StartBackgroundLicenseChecker(const utils::Settings &settings);
|
||||
|
||||
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &GetLicenseInfo();
|
||||
|
||||
private:
|
||||
std::pair<std::string, std::string> GetLicenseInfo(const utils::Settings &settings) const;
|
||||
std::pair<std::string, std::string> ExtractLicenseInfo(const utils::Settings &settings) const;
|
||||
void RevalidateLicense(const utils::Settings &settings);
|
||||
void RevalidateLicense(const std::string &license_key, const std::string &organization_name);
|
||||
|
||||
std::optional<std::pair<std::string, std::string>> license_info_override_;
|
||||
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> previous_license_info_{std::nullopt};
|
||||
bool enterprise_enabled_{false};
|
||||
std::atomic<bool> is_valid_{false};
|
||||
LicenseType license_type_;
|
||||
utils::Scheduler scheduler_;
|
||||
|
||||
friend void RegisterLicenseSettings(LicenseChecker &license_checker, utils::Settings &settings);
|
||||
@ -74,4 +111,4 @@ std::string Encode(const License &license);
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
extern LicenseChecker global_license_checker;
|
||||
} // namespace memgraph::utils::license
|
||||
} // namespace memgraph::license
|
71
src/license/license_sender.cpp
Normal file
71
src/license/license_sender.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
// License, and you may not use this file except in compliance with the Business Source License.
|
||||
//
|
||||
// As of the Change Date specified in that file, in accordance with
|
||||
// the Business Source License, use of this software will be governed
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include "license/license_sender.hpp"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <cstdint>
|
||||
|
||||
#include "requests/requests.hpp"
|
||||
#include "utils/memory_tracker.hpp"
|
||||
#include "utils/stat.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
#include "utils/system_info.hpp"
|
||||
#include "utils/timestamp.hpp"
|
||||
|
||||
namespace memgraph::license {
|
||||
|
||||
LicenseInfoSender::LicenseInfoSender(std::string url, std::string uuid, std::string machine_id, int64_t memory_limit,
|
||||
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &license_info,
|
||||
std::chrono::seconds request_frequency)
|
||||
: url_{std::move(url)},
|
||||
uuid_{std::move(uuid)},
|
||||
machine_id_{std::move(machine_id)},
|
||||
memory_limit_{memory_limit},
|
||||
license_info_{license_info} {
|
||||
scheduler_.Run("LicenseCheck", request_frequency, [&] { SendData(); });
|
||||
}
|
||||
|
||||
LicenseInfoSender::~LicenseInfoSender() { scheduler_.Stop(); }
|
||||
|
||||
void LicenseInfoSender::SendData() {
|
||||
nlohmann::json data = nlohmann::json::object();
|
||||
|
||||
license_info_.WithLock([&data, this](const auto &license_info) mutable {
|
||||
if (license_info && !license_info->organization_name.empty()) {
|
||||
const auto memory_info = utils::GetMemoryInfo();
|
||||
const auto memory_usage = utils::GetMemoryUsage();
|
||||
data = {{"run_id", uuid_},
|
||||
{"machine_id", machine_id_},
|
||||
{"type", "license-check"},
|
||||
{"license_type", LicenseTypeToString(license_info->license.type)},
|
||||
{"license_key", license_info->license_key},
|
||||
{"organization", license_info->organization_name},
|
||||
{"valid", license_info->is_valid},
|
||||
{"physical_memory_size", memory_info.memory},
|
||||
{"swap_memory_size", memory_info.swap},
|
||||
{"memory_used", memory_usage},
|
||||
{"runtime_memory_limit", memory_limit_},
|
||||
{"license_memory_limit", license_info->license.memory_limit},
|
||||
{"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}};
|
||||
}
|
||||
});
|
||||
|
||||
if (data.empty()) {
|
||||
return;
|
||||
}
|
||||
if (!requests::RequestPostJson(url_, data,
|
||||
/* timeout_in_seconds = */ 2 * 60)) {
|
||||
spdlog::trace("Cannot send license information, enable {} availability!", url_);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace memgraph::license
|
50
src/license/license_sender.hpp
Normal file
50
src/license/license_sender.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
// License, and you may not use this file except in compliance with the Business Source License.
|
||||
//
|
||||
// As of the Change Date specified in that file, in accordance with
|
||||
// the Business Source License, use of this software will be governed
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <json/json.hpp>
|
||||
|
||||
#include "license/license.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
#include "utils/timer.hpp"
|
||||
|
||||
namespace memgraph::license {
|
||||
|
||||
class LicenseInfoSender final {
|
||||
public:
|
||||
LicenseInfoSender(std::string url, std::string uuid, std::string machine_id, int64_t memory_limit,
|
||||
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &license_info,
|
||||
std::chrono::seconds request_frequency = std::chrono::seconds(8 * 60 * 60));
|
||||
|
||||
LicenseInfoSender(const LicenseInfoSender &) = delete;
|
||||
LicenseInfoSender(LicenseInfoSender &&) noexcept = delete;
|
||||
LicenseInfoSender &operator=(const LicenseInfoSender &) = delete;
|
||||
LicenseInfoSender &operator=(LicenseInfoSender &&) noexcept = delete;
|
||||
~LicenseInfoSender();
|
||||
|
||||
private:
|
||||
void SendData();
|
||||
|
||||
const std::string url_;
|
||||
const std::string uuid_;
|
||||
const std::string machine_id_;
|
||||
const int64_t memory_limit_;
|
||||
|
||||
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &license_info_;
|
||||
utils::Scheduler scheduler_;
|
||||
};
|
||||
|
||||
} // namespace memgraph::license
|
@ -40,6 +40,8 @@
|
||||
#include "glue/auth_checker.hpp"
|
||||
#include "glue/auth_handler.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "license/license_sender.hpp"
|
||||
#include "py/py.hpp"
|
||||
#include "query/auth_checker.hpp"
|
||||
#include "query/discard_value_stream.hpp"
|
||||
@ -57,7 +59,6 @@
|
||||
#include "utils/event_counter.hpp"
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/flag_validation.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/memory_tracker.hpp"
|
||||
#include "utils/message.hpp"
|
||||
@ -68,6 +69,7 @@
|
||||
#include "utils/string.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
#include "utils/sysinfo/memory.hpp"
|
||||
#include "utils/system_info.hpp"
|
||||
#include "utils/terminate_handler.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
@ -506,7 +508,7 @@ class BoltSession final : public memgraph::communication::bolt::Session<memgraph
|
||||
username = &user_->username();
|
||||
}
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
audit_log_->Record(endpoint_.address().to_string(), user_ ? *username : "", query,
|
||||
memgraph::storage::PropertyValue(params_pv));
|
||||
}
|
||||
@ -779,15 +781,15 @@ int main(int argc, char **argv) {
|
||||
memgraph::utils::OnScopeExit settings_finalizer([&] { memgraph::utils::global_settings.Finalize(); });
|
||||
|
||||
// register all runtime settings
|
||||
memgraph::utils::license::RegisterLicenseSettings(memgraph::utils::license::global_license_checker,
|
||||
memgraph::utils::global_settings);
|
||||
memgraph::license::RegisterLicenseSettings(memgraph::license::global_license_checker,
|
||||
memgraph::utils::global_settings);
|
||||
|
||||
memgraph::utils::license::global_license_checker.CheckEnvLicense();
|
||||
memgraph::license::global_license_checker.CheckEnvLicense();
|
||||
if (!FLAGS_organization_name.empty() && !FLAGS_license_key.empty()) {
|
||||
memgraph::utils::license::global_license_checker.SetLicenseInfoOverride(FLAGS_license_key, FLAGS_organization_name);
|
||||
memgraph::license::global_license_checker.SetLicenseInfoOverride(FLAGS_license_key, FLAGS_organization_name);
|
||||
}
|
||||
|
||||
memgraph::utils::license::global_license_checker.StartBackgroundLicenseChecker(memgraph::utils::global_settings);
|
||||
memgraph::license::global_license_checker.StartBackgroundLicenseChecker(memgraph::utils::global_settings);
|
||||
|
||||
// All enterprise features should be constructed before the main database
|
||||
// storage. This will cause them to be destructed *after* the main database
|
||||
@ -906,12 +908,15 @@ int main(int argc, char **argv) {
|
||||
ServerT server(server_endpoint, &session_data, &context, FLAGS_bolt_session_inactivity_timeout, service_name,
|
||||
FLAGS_bolt_num_workers);
|
||||
|
||||
const auto run_id = memgraph::utils::GenerateUUID();
|
||||
const auto machine_id = memgraph::utils::GetMachineId();
|
||||
session_data.run_id = run_id;
|
||||
|
||||
// Setup telemetry
|
||||
static constexpr auto telemetry_server{"https://telemetry.memgraph.com/88b5e7e8-746a-11e8-9f85-538a9e9690cc/"};
|
||||
std::optional<memgraph::telemetry::Telemetry> telemetry;
|
||||
if (FLAGS_telemetry_enabled) {
|
||||
telemetry.emplace("https://telemetry.memgraph.com/88b5e7e8-746a-11e8-9f85-538a9e9690cc/",
|
||||
data_directory / "telemetry", std::chrono::minutes(10));
|
||||
session_data.run_id = telemetry->GetRunId();
|
||||
telemetry.emplace(telemetry_server, data_directory / "telemetry", run_id, machine_id, std::chrono::minutes(10));
|
||||
telemetry->AddCollector("storage", [&db]() -> nlohmann::json {
|
||||
auto info = db.GetInfo();
|
||||
return {{"vertices", info.vertex_count}, {"edges", info.edge_count}};
|
||||
@ -927,6 +932,8 @@ int main(int argc, char **argv) {
|
||||
return memgraph::query::plan::CallProcedure::GetAndResetCounters();
|
||||
});
|
||||
}
|
||||
memgraph::license::LicenseInfoSender license_info_sender(telemetry_server, run_id, machine_id, memory_limit,
|
||||
memgraph::license::global_license_checker.GetLicenseInfo());
|
||||
|
||||
memgraph::communication::websocket::SafeAuth websocket_auth{&auth};
|
||||
memgraph::communication::websocket::Server websocket_server{
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "auth/models.hpp"
|
||||
#include "glue/communication.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "memory/memory_control.hpp"
|
||||
#include "query/constants.hpp"
|
||||
#include "query/context.hpp"
|
||||
@ -54,7 +55,6 @@
|
||||
#include "utils/event_counter.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/flag_validation.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/likely.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/memory.hpp"
|
||||
@ -299,7 +299,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa
|
||||
|
||||
Callback callback;
|
||||
|
||||
const auto license_check_result = utils::license::global_license_checker.IsValidLicense(utils::global_settings);
|
||||
const auto license_check_result = license::global_license_checker.IsEnterpriseValid(utils::global_settings);
|
||||
|
||||
static const std::unordered_set enterprise_only_methods{
|
||||
AuthQuery::Action::CREATE_ROLE, AuthQuery::Action::DROP_ROLE, AuthQuery::Action::SET_ROLE,
|
||||
@ -309,7 +309,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa
|
||||
|
||||
if (license_check_result.HasError() && enterprise_only_methods.contains(auth_query->action_)) {
|
||||
throw utils::BasicException(
|
||||
utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "advanced authentication features"));
|
||||
license::LicenseCheckErrorToString(license_check_result.GetError(), "advanced authentication features"));
|
||||
}
|
||||
|
||||
switch (auth_query->action_) {
|
||||
@ -1017,7 +1017,7 @@ PullPlan::PullPlan(const std::shared_ptr<CachedPlan> plan, const Parameters &par
|
||||
ctx_.evaluation_context.properties = NamesToProperties(plan->ast_storage().properties_, dba);
|
||||
ctx_.evaluation_context.labels = NamesToLabels(plan->ast_storage().labels_, dba);
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && username.has_value() && dba) {
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && username.has_value() && dba) {
|
||||
ctx_.auth_checker = interpreter_context->auth_checker->GetFineGrainedAuthChecker(*username, dba);
|
||||
}
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <cppitertools/imap.hpp>
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#include "license/license.hpp"
|
||||
#include "query/auth_checker.hpp"
|
||||
#include "query/context.hpp"
|
||||
#include "query/db_accessor.hpp"
|
||||
@ -47,7 +48,6 @@
|
||||
#include "utils/event_counter.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/fnv.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/likely.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/memory.hpp"
|
||||
@ -242,7 +242,7 @@ CreateNode::CreateNodeCursor::CreateNodeCursor(const CreateNode &self, utils::Me
|
||||
bool CreateNode::CreateNodeCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
SCOPED_PROFILE_OP("CreateNode");
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(self_.node_info_.labels,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
throw QueryRuntimeException("Vertex not created due to not having enough permission!");
|
||||
@ -334,7 +334,7 @@ bool CreateExpand::CreateExpandCursor::Pull(Frame &frame, ExecutionContext &cont
|
||||
if (!input_cursor_->Pull(frame, context)) return false;
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
const auto fine_grained_permission = self_.existing_node_
|
||||
? memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE
|
||||
|
||||
@ -433,8 +433,7 @@ class ScanAllCursor : public Cursor {
|
||||
vertices_it_.emplace(vertices_.value().begin());
|
||||
}
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
!FindNextVertex(context)) {
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker && !FindNextVertex(context)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -731,7 +730,7 @@ bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
if (in_edges_ && *in_edges_it_ != in_edges_->end()) {
|
||||
auto edge = *(*in_edges_it_)++;
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge.From(), self_.view_,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -752,7 +751,7 @@ bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
// already done in the block above
|
||||
if (self_.common_.direction == EdgeAtom::Direction::BOTH && edge.IsCycle()) continue;
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge.To(), self_.view_,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1089,7 +1088,7 @@ class ExpandVariableCursor : public Cursor {
|
||||
VertexAccessor current_vertex =
|
||||
current_edge.second == EdgeAtom::Direction::IN ? current_edge.first.From() : current_edge.first.To();
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(current_edge.first, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(current_vertex, storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1258,7 +1257,7 @@ class STShortestPathCursor : public query::plan::Cursor {
|
||||
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
||||
for (const auto &edge : out_edges) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge.To(), storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1284,7 +1283,7 @@ class STShortestPathCursor : public query::plan::Cursor {
|
||||
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
||||
for (const auto &edge : in_edges) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge.From(), storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1324,7 +1323,7 @@ class STShortestPathCursor : public query::plan::Cursor {
|
||||
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
||||
for (const auto &edge : out_edges) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge.To(), storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1349,7 +1348,7 @@ class STShortestPathCursor : public query::plan::Cursor {
|
||||
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
||||
for (const auto &edge : in_edges) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge.From(), storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1406,7 +1405,7 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor {
|
||||
// if we already processed the given vertex it doesn't get expanded
|
||||
if (processed_.find(vertex) != processed_.end()) return;
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(vertex, storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1592,7 +1591,7 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor {
|
||||
int64_t depth) {
|
||||
auto *memory = evaluator.GetMemoryResource();
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(vertex, storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1902,7 +1901,7 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor {
|
||||
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
||||
for (const auto &edge : out_edges) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(edge.To(), storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1916,7 +1915,7 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor {
|
||||
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
||||
for (const auto &edge : in_edges) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(edge.From(), storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||
@ -1973,7 +1972,6 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor {
|
||||
edges_on_frame.emplace(edges_on_frame.begin(), current_edge);
|
||||
|
||||
auto next_vertex = current_edge_direction == EdgeAtom::Direction::IN ? current_edge.From() : current_edge.To();
|
||||
frame[self_.common_.node_symbol] = next_vertex;
|
||||
frame[self_.total_weight_.value()] = current_weight;
|
||||
|
||||
if (next_edges_.find({next_vertex, traversal_stack_.size()}) != next_edges_.end()) {
|
||||
@ -1986,6 +1984,15 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor {
|
||||
}
|
||||
|
||||
if ((current_weight > visited_cost_.at(next_vertex)).ValueBool()) continue;
|
||||
|
||||
// Place destination node on the frame, handle existence flag
|
||||
if (self_.common_.existing_node) {
|
||||
const auto &node = frame[self_.common_.node_symbol];
|
||||
ExpectType(self_.common_.node_symbol, node, TypedValue::Type::Vertex);
|
||||
if (node.ValueVertex() != next_vertex) continue;
|
||||
} else {
|
||||
frame[self_.common_.node_symbol] = next_vertex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2366,7 +2373,7 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
if (expression_result.type() == TypedValue::Type::Edge) {
|
||||
auto &ea = expression_result.ValueEdge();
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!(context.auth_checker->Has(ea, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE) &&
|
||||
context.auth_checker->Has(ea.To(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
||||
context.auth_checker->Has(ea.From(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE))) {
|
||||
@ -2399,7 +2406,7 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
case TypedValue::Type::Vertex: {
|
||||
auto &va = expression_result.ValueVertex();
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(va, storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
throw QueryRuntimeException("Vertex not deleted due to not having enough permission!");
|
||||
}
|
||||
@ -2508,7 +2515,7 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex
|
||||
switch (lhs.type()) {
|
||||
case TypedValue::Type::Vertex: {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw QueryRuntimeException("Vertex property not set due to not having enough permission!");
|
||||
@ -2525,7 +2532,7 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex
|
||||
}
|
||||
case TypedValue::Type::Edge: {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw QueryRuntimeException("Edge property not set due to not having enough permission!");
|
||||
}
|
||||
@ -2724,7 +2731,7 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, ExecutionContext &co
|
||||
switch (lhs.type()) {
|
||||
case TypedValue::Type::Vertex:
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw QueryRuntimeException("Vertex properties not set due to not having enough permission!");
|
||||
@ -2735,7 +2742,7 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, ExecutionContext &co
|
||||
break;
|
||||
case TypedValue::Type::Edge:
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw QueryRuntimeException("Edge properties not set due to not having enough permission!");
|
||||
}
|
||||
@ -2778,7 +2785,7 @@ bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
SCOPED_PROFILE_OP("SetLabels");
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
throw QueryRuntimeException("Couldn't set label due to not having enough permission!");
|
||||
}
|
||||
@ -2793,7 +2800,7 @@ bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
auto &vertex = vertex_value.ValueVertex();
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(vertex, storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw QueryRuntimeException("Couldn't set label due to not having enough permission!");
|
||||
@ -2883,7 +2890,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, ExecutionContext &
|
||||
switch (lhs.type()) {
|
||||
case TypedValue::Type::Vertex:
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw QueryRuntimeException("Vertex property not removed due to not having enough permission!");
|
||||
@ -2893,7 +2900,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, ExecutionContext &
|
||||
break;
|
||||
case TypedValue::Type::Edge:
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw QueryRuntimeException("Edge property not removed due to not having enough permission!");
|
||||
}
|
||||
@ -2936,7 +2943,7 @@ bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, ExecutionContext &cont
|
||||
SCOPED_PROFILE_OP("RemoveLabels");
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
throw QueryRuntimeException("Couldn't remove label due to not having enough permission!");
|
||||
}
|
||||
@ -2951,7 +2958,7 @@ bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, ExecutionContext &cont
|
||||
auto &vertex = vertex_value.ValueVertex();
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
||||
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||
!context.auth_checker->Has(vertex, storage::View::OLD,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw QueryRuntimeException("Couldn't remove label due to not having enough permission!");
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "license/license.hpp"
|
||||
#include "mg_procedure.h"
|
||||
#include "module.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
@ -32,7 +33,6 @@
|
||||
#include "storage/v2/view.hpp"
|
||||
#include "utils/algorithm.hpp"
|
||||
#include "utils/concepts.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/math.hpp"
|
||||
#include "utils/memory.hpp"
|
||||
@ -1653,7 +1653,7 @@ mgp_error mgp_vertex_set_property(struct mgp_vertex *v, const char *property_nam
|
||||
auto *ctx = v->graph->ctx;
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||
!ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw AuthorizationException{"Insufficient permissions for setting a property on vertex!"};
|
||||
@ -1706,7 +1706,7 @@ mgp_error mgp_vertex_add_label(struct mgp_vertex *v, mgp_label label) {
|
||||
const auto label_id = std::visit([label](auto *impl) { return impl->NameToLabel(label.name); }, v->graph->impl);
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||
!(ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
||||
ctx->auth_checker->Has({label_id}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) {
|
||||
@ -1750,7 +1750,7 @@ mgp_error mgp_vertex_remove_label(struct mgp_vertex *v, mgp_label label) {
|
||||
const auto label_id = std::visit([&label](auto *impl) { return impl->NameToLabel(label.name); }, v->graph->impl);
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||
!(ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
||||
ctx->auth_checker->Has({label_id}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) {
|
||||
@ -1989,7 +1989,7 @@ mgp_error mgp_vertex_iter_in_edges(mgp_vertex *v, mgp_memory *memory, mgp_edges_
|
||||
it->in.emplace(std::move(*maybe_edges));
|
||||
it->in_it.emplace(it->in->begin());
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
NextPermittedEdge(*it, true);
|
||||
}
|
||||
#endif
|
||||
@ -2041,7 +2041,7 @@ mgp_error mgp_vertex_iter_out_edges(mgp_vertex *v, mgp_memory *memory, mgp_edges
|
||||
it->out_it.emplace(it->out->begin());
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
NextPermittedEdge(*it, false);
|
||||
}
|
||||
#endif
|
||||
@ -2099,7 +2099,7 @@ mgp_error mgp_edges_iterator_next(mgp_edges_iterator *it, mgp_edge **result) {
|
||||
++*impl_it;
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
NextPermittedEdge(*it, for_in);
|
||||
}
|
||||
#endif
|
||||
@ -2124,10 +2124,7 @@ mgp_error mgp_edges_iterator_next(mgp_edges_iterator *it, mgp_edge **result) {
|
||||
return &*it->current_e;
|
||||
};
|
||||
if (it->in_it) {
|
||||
auto *result = next(true);
|
||||
if (result != nullptr) {
|
||||
return result;
|
||||
}
|
||||
return next(true);
|
||||
}
|
||||
return next(false);
|
||||
},
|
||||
@ -2205,7 +2202,7 @@ mgp_error mgp_edge_set_property(struct mgp_edge *e, const char *property_name, m
|
||||
auto *ctx = e->from.graph->ctx;
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||
!ctx->auth_checker->Has(e->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
throw AuthorizationException{"Insufficient permissions for setting a property on edge!"};
|
||||
}
|
||||
@ -2313,7 +2310,7 @@ mgp_error mgp_graph_create_vertex(struct mgp_graph *graph, mgp_memory *memory, m
|
||||
[=]() -> mgp_vertex * {
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && graph->ctx &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && graph->ctx &&
|
||||
graph->ctx->auth_checker &&
|
||||
!graph->ctx->auth_checker->HasGlobalPrivilegeOnVertices(
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
@ -2343,7 +2340,7 @@ mgp_error mgp_graph_delete_vertex(struct mgp_graph *graph, mgp_vertex *vertex) {
|
||||
auto *ctx = graph->ctx;
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||
!ctx->auth_checker->Has(vertex->getImpl(), graph->view,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
throw AuthorizationException{"Insufficient permissions for deleting a vertex!"};
|
||||
@ -2394,7 +2391,7 @@ mgp_error mgp_graph_detach_delete_vertex(struct mgp_graph *graph, mgp_vertex *ve
|
||||
return WrapExceptions([=] {
|
||||
auto *ctx = graph->ctx;
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||
!ctx->auth_checker->Has(vertex->getImpl(), graph->view,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
throw AuthorizationException{"Insufficient permissions for deleting a vertex!"};
|
||||
@ -2458,7 +2455,7 @@ mgp_error mgp_graph_create_edge(mgp_graph *graph, mgp_vertex *from, mgp_vertex *
|
||||
#ifdef MG_ENTERPRISE
|
||||
const auto edge_id =
|
||||
std::visit([type](auto *impl) { return impl->NameToEdgeType(type.name); }, from->graph->impl);
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||
!ctx->auth_checker->Has(edge_id, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
throw AuthorizationException{"Insufficient permissions for creating edges!"};
|
||||
}
|
||||
@ -2519,7 +2516,7 @@ mgp_error mgp_graph_delete_edge(struct mgp_graph *graph, mgp_edge *edge) {
|
||||
return WrapExceptions([=] {
|
||||
auto *ctx = graph->ctx;
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||
!ctx->auth_checker->Has(edge->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
throw AuthorizationException{"Insufficient permissions for deleting an edge!"};
|
||||
}
|
||||
@ -2581,7 +2578,7 @@ mgp_vertices_iterator::mgp_vertices_iterator(mgp_graph *graph, memgraph::utils::
|
||||
vertices(std::visit([graph](auto *impl) { return impl->Vertices(graph->view); }, graph->impl)),
|
||||
current_it(vertices.begin()) {
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
NextPermitted(*this);
|
||||
}
|
||||
#endif
|
||||
@ -2630,7 +2627,7 @@ mgp_error mgp_vertices_iterator_next(mgp_vertices_iterator *it, mgp_vertex **res
|
||||
|
||||
++it->current_it;
|
||||
#ifdef MG_ENTERPRISE
|
||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
||||
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||
NextPermitted(*it);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,12 +1,12 @@
|
||||
set(telemetry_src_files
|
||||
collectors.cpp
|
||||
telemetry.cpp
|
||||
system_info.cpp)
|
||||
collectors.cpp
|
||||
telemetry.cpp)
|
||||
|
||||
add_library(telemetry_lib STATIC ${telemetry_src_files})
|
||||
target_link_libraries(telemetry_lib mg-requests mg-kvstore mg-utils)
|
||||
add_library(mg-telemetry STATIC ${telemetry_src_files})
|
||||
target_link_libraries(mg-telemetry mg-requests mg-kvstore mg-utils)
|
||||
option(MG_TELEMETRY_ID_OVERRIDE "Override for the telemetry ID" STRING)
|
||||
if (MG_TELEMETRY_ID_OVERRIDE)
|
||||
|
||||
if(MG_TELEMETRY_ID_OVERRIDE)
|
||||
message(WARNING "Using telemetry ID override: ${MG_TELEMETRY_ID_OVERRIDE}")
|
||||
target_compile_definitions(telemetry_lib PRIVATE MG_TELEMETRY_ID_OVERRIDE="${MG_TELEMETRY_ID_OVERRIDE}")
|
||||
target_compile_definitions(mg-telemetry PRIVATE MG_TELEMETRY_ID_OVERRIDE="${MG_TELEMETRY_ID_OVERRIDE}")
|
||||
endif()
|
||||
|
@ -17,38 +17,24 @@
|
||||
|
||||
#include "requests/requests.hpp"
|
||||
#include "telemetry/collectors.hpp"
|
||||
#include "telemetry/system_info.hpp"
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/system_info.hpp"
|
||||
#include "utils/timestamp.hpp"
|
||||
#include "utils/uuid.hpp"
|
||||
|
||||
namespace memgraph::telemetry {
|
||||
namespace {
|
||||
std::string GetMachineId() {
|
||||
#ifdef MG_TELEMETRY_ID_OVERRIDE
|
||||
return MG_TELEMETRY_ID_OVERRIDE;
|
||||
#else
|
||||
// We assume we're on linux and we need to read the machine id from /etc/machine-id
|
||||
const auto machine_id_lines = utils::ReadLines("/etc/machine-id");
|
||||
if (machine_id_lines.size() != 1) {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return machine_id_lines[0];
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const int kMaxBatchSize = 100;
|
||||
constexpr auto kMaxBatchSize{100};
|
||||
|
||||
Telemetry::Telemetry(std::string url, std::filesystem::path storage_directory,
|
||||
Telemetry::Telemetry(std::string url, std::filesystem::path storage_directory, std::string uuid, std::string machine_id,
|
||||
std::chrono::duration<int64_t> refresh_interval, const uint64_t send_every_n)
|
||||
: url_(std::move(url)),
|
||||
uuid_(utils::GenerateUUID()),
|
||||
machine_id_(GetMachineId()),
|
||||
uuid_(uuid),
|
||||
machine_id_(machine_id),
|
||||
send_every_n_(send_every_n),
|
||||
storage_(std::move(storage_directory)) {
|
||||
StoreData("startup", GetSystemInfo());
|
||||
StoreData("startup", utils::GetSystemInfo());
|
||||
AddCollector("resources", GetResourceUsage);
|
||||
AddCollector("uptime", [&]() -> nlohmann::json { return GetUptime(); });
|
||||
scheduler_.Run("Telemetry", refresh_interval, [&] { CollectData(); });
|
||||
@ -59,19 +45,15 @@ void Telemetry::AddCollector(const std::string &name, const std::function<const
|
||||
collectors_.emplace_back(name, func);
|
||||
}
|
||||
|
||||
std::string Telemetry::GetRunId() const { return uuid_; }
|
||||
|
||||
Telemetry::~Telemetry() {
|
||||
scheduler_.Stop();
|
||||
CollectData("shutdown");
|
||||
}
|
||||
|
||||
void Telemetry::StoreData(const nlohmann::json &event, const nlohmann::json &data) {
|
||||
nlohmann::json payload = {{"run_id", uuid_},
|
||||
{"machine_id", machine_id_},
|
||||
{"event", event},
|
||||
{"data", data},
|
||||
{"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}};
|
||||
nlohmann::json payload = {
|
||||
{"run_id", uuid_}, {"type", "telemetry"}, {"machine_id", machine_id_},
|
||||
{"event", event}, {"data", data}, {"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}};
|
||||
storage_.Put(fmt::format("{}:{}", uuid_, event.dump()), payload.dump());
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace memgraph::telemetry {
|
||||
* This class implements the telemetry collector service. It periodically scapes
|
||||
* all registered collectors and stores their data. With periodically scraping
|
||||
* the collectors the service collects machine information in the constructor
|
||||
* and stores it. Also, it calles all collectors once more in the destructor so
|
||||
* and stores it. Also, it calls all collectors once more in the destructor so
|
||||
* that final stats can be collected. All data is stored persistently. If there
|
||||
* is no internet connection the data will be sent when the internet connection
|
||||
* is reestablished. If there is an issue with the internet connection that
|
||||
@ -34,14 +34,11 @@ namespace memgraph::telemetry {
|
||||
*/
|
||||
class Telemetry final {
|
||||
public:
|
||||
Telemetry(std::string url, std::filesystem::path storage_directory,
|
||||
Telemetry(std::string url, std::filesystem::path storage_directory, std::string uuid, std::string machine_id,
|
||||
std::chrono::duration<int64_t> refresh_interval = std::chrono::minutes(10), uint64_t send_every_n = 10);
|
||||
|
||||
void AddCollector(const std::string &name, const std::function<const nlohmann::json(void)> &func);
|
||||
|
||||
/// Required to expose run_id to Bolt server.
|
||||
std::string GetRunId() const;
|
||||
|
||||
~Telemetry();
|
||||
|
||||
Telemetry(const Telemetry &) = delete;
|
||||
|
@ -14,6 +14,7 @@ set(utils_src_files
|
||||
thread.cpp
|
||||
thread_pool.cpp
|
||||
tsc.cpp
|
||||
system_info.cpp
|
||||
uuid.cpp)
|
||||
|
||||
find_package(Boost REQUIRED)
|
||||
@ -23,16 +24,10 @@ find_package(Threads REQUIRED)
|
||||
|
||||
add_library(mg-utils STATIC ${utils_src_files})
|
||||
target_link_libraries(mg-utils PUBLIC Boost::headers fmt::fmt spdlog::spdlog)
|
||||
target_link_libraries(mg-utils PRIVATE librdtsc stdc++fs Threads::Threads gflags uuid rt)
|
||||
target_link_libraries(mg-utils PRIVATE librdtsc stdc++fs Threads::Threads gflags json uuid rt)
|
||||
|
||||
set(settings_src_files
|
||||
settings.cpp)
|
||||
|
||||
add_library(mg-settings STATIC ${settings_src_files})
|
||||
target_link_libraries(mg-settings mg-kvstore mg-slk mg-utils)
|
||||
|
||||
set(license_src_files
|
||||
license.cpp)
|
||||
add_library(mg-license STATIC ${license_src_files})
|
||||
target_link_libraries(mg-license mg-settings mg-utils)
|
||||
|
||||
|
@ -43,7 +43,7 @@ inline uint64_t GetMemoryUsage() {
|
||||
pid_t pid = getpid();
|
||||
uint64_t memory = 0;
|
||||
auto statm_data = utils::ReadLines(fmt::format("/proc/{}/statm", pid));
|
||||
if (statm_data.size() >= 1) {
|
||||
if (!statm_data.empty()) {
|
||||
auto split = utils::Split(statm_data[0]);
|
||||
if (split.size() >= 2) {
|
||||
memory = std::stoull(split[1]) * sysconf(_SC_PAGESIZE);
|
||||
|
@ -9,56 +9,35 @@
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include "telemetry/system_info.hpp"
|
||||
#include "utils/system_info.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace memgraph::telemetry {
|
||||
namespace memgraph::utils {
|
||||
|
||||
const nlohmann::json GetSystemInfo() {
|
||||
// Get `uname`.
|
||||
struct utsname info;
|
||||
if (uname(&info) != 0) return {};
|
||||
|
||||
// Parse `/etc/os-release`.
|
||||
std::string os_name, os_version, os_full;
|
||||
auto os_data = utils::ReadLines("/etc/os-release");
|
||||
for (auto &row : os_data) {
|
||||
auto split = utils::Split(row, "=");
|
||||
if (split.size() < 2) continue;
|
||||
if (split[0] == "NAME") {
|
||||
os_name = utils::Trim(split[1], "\"");
|
||||
} else if (split[0] == "VERSION") {
|
||||
os_version = utils::Trim(split[1], "\"");
|
||||
}
|
||||
os_full = fmt::format("{} {}", os_name, os_version);
|
||||
}
|
||||
|
||||
// Parse `/proc/cpuinfo`.
|
||||
std::string cpu_model;
|
||||
uint64_t cpu_count = 0;
|
||||
auto cpu_data = utils::ReadLines("/proc/cpuinfo");
|
||||
for (auto &row : cpu_data) {
|
||||
auto tmp = utils::Trim(row);
|
||||
if (tmp == "") {
|
||||
++cpu_count;
|
||||
} else if (utils::StartsWith(tmp, "model name")) {
|
||||
auto split = utils::Split(tmp, ":");
|
||||
if (split.size() != 2) continue;
|
||||
cpu_model = utils::Trim(split[1]);
|
||||
}
|
||||
std::string GetMachineId() {
|
||||
#ifdef MG_TELEMETRY_ID_OVERRIDE
|
||||
return MG_TELEMETRY_ID_OVERRIDE;
|
||||
#else
|
||||
// We assume we're on linux and we need to read the machine id from /etc/machine-id
|
||||
const auto machine_id_lines = memgraph::utils::ReadLines("/etc/machine-id");
|
||||
if (machine_id_lines.size() != 1) {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return machine_id_lines[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
MemoryInfo GetMemoryInfo() {
|
||||
// Parse `/proc/meminfo`.
|
||||
nlohmann::json ret;
|
||||
uint64_t memory = 0, swap = 0;
|
||||
uint64_t memory{0};
|
||||
uint64_t swap{0};
|
||||
auto mem_data = utils::ReadLines("/proc/meminfo");
|
||||
for (auto &row : mem_data) {
|
||||
auto tmp = utils::Trim(row);
|
||||
@ -74,15 +53,55 @@ const nlohmann::json GetSystemInfo() {
|
||||
}
|
||||
memory *= 1024;
|
||||
swap *= 1024;
|
||||
|
||||
return {{"architecture", info.machine},
|
||||
{"cpu_count", cpu_count},
|
||||
{"cpu_model", cpu_model},
|
||||
{"kernel", fmt::format("{} {}", info.release, info.version)},
|
||||
{"memory", memory},
|
||||
{"os", os_full},
|
||||
{"swap", swap},
|
||||
{"version", gflags::VersionString()}};
|
||||
return {memory, swap};
|
||||
}
|
||||
|
||||
} // namespace memgraph::telemetry
|
||||
CPUInfo GetCPUInfo() {
|
||||
// Parse `/proc/cpuinfo`.
|
||||
std::string cpu_model;
|
||||
uint64_t cpu_count{0};
|
||||
auto cpu_data = utils::ReadLines("/proc/cpuinfo");
|
||||
for (auto &row : cpu_data) {
|
||||
auto tmp = utils::Trim(row);
|
||||
if (tmp.empty()) {
|
||||
++cpu_count;
|
||||
} else if (utils::StartsWith(tmp, "model name")) {
|
||||
auto split = utils::Split(tmp, ":");
|
||||
if (split.size() != 2) continue;
|
||||
cpu_model = utils::Trim(split[1]);
|
||||
}
|
||||
}
|
||||
return {cpu_model, cpu_count};
|
||||
}
|
||||
|
||||
nlohmann::json GetSystemInfo() {
|
||||
// Get `uname`.
|
||||
struct utsname info;
|
||||
if (uname(&info) != 0) return {};
|
||||
|
||||
// Parse `/etc/os-release`.
|
||||
std::string os_name;
|
||||
std::string os_version;
|
||||
std::string os_full;
|
||||
auto os_data = utils::ReadLines("/etc/os-release");
|
||||
for (auto &row : os_data) {
|
||||
auto split = utils::Split(row, "=");
|
||||
if (split.size() < 2) continue;
|
||||
if (split[0] == "NAME") {
|
||||
os_name = utils::Trim(split[1], "\"");
|
||||
} else if (split[0] == "VERSION") {
|
||||
os_version = utils::Trim(split[1], "\"");
|
||||
}
|
||||
os_full = fmt::format("{} {}", os_name, os_version);
|
||||
}
|
||||
|
||||
const auto cpu_info = GetCPUInfo();
|
||||
const auto mem_info = GetMemoryInfo();
|
||||
|
||||
return {{"architecture", info.machine}, {"cpu_count", cpu_info.cpu_count},
|
||||
{"cpu_model", cpu_info.cpu_model}, {"kernel", fmt::format("{} {}", info.release, info.version)},
|
||||
{"memory", mem_info.memory}, {"os", os_full},
|
||||
{"swap", mem_info.swap}, {"version", gflags::VersionString()}};
|
||||
}
|
||||
|
||||
} // namespace memgraph::utils
|
@ -11,16 +11,33 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <json/json.hpp>
|
||||
|
||||
namespace memgraph::telemetry {
|
||||
namespace memgraph::utils {
|
||||
|
||||
// TODO (mferencevic): merge with `utils/sysinfo`
|
||||
struct MemoryInfo {
|
||||
uint64_t memory;
|
||||
uint64_t swap;
|
||||
};
|
||||
|
||||
struct CPUInfo {
|
||||
std::string cpu_model;
|
||||
uint64_t cpu_count;
|
||||
};
|
||||
|
||||
std::string GetMachineId();
|
||||
|
||||
MemoryInfo GetMemoryInfo();
|
||||
|
||||
CPUInfo GetCPUInfo();
|
||||
|
||||
/**
|
||||
* This function returs a dictionary containing some basic system information
|
||||
* This function return a dictionary containing some basic system information
|
||||
* (eg. operating system name, cpu information, memory information, etc.).
|
||||
*/
|
||||
const nlohmann::json GetSystemInfo();
|
||||
nlohmann::json GetSystemInfo();
|
||||
|
||||
} // namespace memgraph::telemetry
|
||||
} // namespace memgraph::utils
|
@ -13,24 +13,6 @@ add_subdirectory(auth)
|
||||
# lba test binaries
|
||||
add_subdirectory(fine_grained_access)
|
||||
|
||||
## distributed ha/basic binaries
|
||||
#add_subdirectory(ha/basic)
|
||||
#
|
||||
## distributed ha/constraints binaries
|
||||
#add_subdirectory(ha/constraints)
|
||||
#
|
||||
## distributed ha/index binaries
|
||||
#add_subdirectory(ha/index)
|
||||
#
|
||||
## distributed ha/large_log_entries binaries
|
||||
#add_subdirectory(ha/large_log_entries)
|
||||
#
|
||||
## distributed ha/leader_election binaries
|
||||
#add_subdirectory(ha/leader_election)
|
||||
#
|
||||
## distributed ha/term_updates binaries
|
||||
#add_subdirectory(ha/term_updates)
|
||||
|
||||
# audit test binaries
|
||||
add_subdirectory(audit)
|
||||
|
||||
@ -39,3 +21,6 @@ add_subdirectory(ldap)
|
||||
|
||||
# mg_import_csv test binaries
|
||||
add_subdirectory(mg_import_csv)
|
||||
|
||||
# license_check test binaries
|
||||
add_subdirectory(license_info)
|
||||
|
6
tests/integration/license_info/CMakeLists.txt
Normal file
6
tests/integration/license_info/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
set(target_name memgraph__integration__license_info)
|
||||
set(client_target_name ${target_name}__client)
|
||||
|
||||
add_executable(${client_target_name} client.cpp)
|
||||
set_target_properties(${client_target_name} PROPERTIES OUTPUT_NAME client)
|
||||
target_link_libraries(${client_target_name} mg-requests mg-license mg-utils)
|
62
tests/integration/license_info/client.cpp
Normal file
62
tests/integration/license_info/client.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
// License, and you may not use this file except in compliance with the Business Source License.
|
||||
//
|
||||
// As of the Change Date specified in that file, in accordance with
|
||||
// the Business Source License, use of this software will be governed
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#include "license/license.hpp"
|
||||
#include "license/license_sender.hpp"
|
||||
#include "requests/requests.hpp"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
#include "utils/system_info.hpp"
|
||||
#include "utils/uuid.hpp"
|
||||
|
||||
DEFINE_string(endpoint, "http://127.0.0.1:5500/", "Endpoint that should be used for the test.");
|
||||
DEFINE_string(license_type, "enterprise", "License type; can be oem or enterprise.");
|
||||
DEFINE_int64(interval, 1, "Interval used for reporting telemetry in seconds.");
|
||||
DEFINE_int64(duration, 10, "Duration of the test in seconds.");
|
||||
|
||||
memgraph::license::LicenseType StringToLicenseType(const std::string_view license_type) {
|
||||
if (license_type == "enterprise") {
|
||||
return memgraph::license::LicenseType::ENTERPRISE;
|
||||
}
|
||||
if (license_type == "oem") {
|
||||
return memgraph::license::LicenseType::OEM;
|
||||
}
|
||||
spdlog::critical("Invalid license type!");
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
gflags::SetVersionString("license-info");
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
memgraph::requests::Init();
|
||||
|
||||
memgraph::license::License license{"Memgraph", 0, 0, StringToLicenseType(FLAGS_license_type)};
|
||||
memgraph::utils::Synchronized<std::optional<memgraph::license::LicenseInfo>, memgraph::utils::SpinLock> license_info{
|
||||
memgraph::license::LicenseInfo{"mg-testkey", "Memgraph"}};
|
||||
license_info.WithLock([license = std::move(license)](auto &license_info) {
|
||||
license_info->license = license;
|
||||
license_info->is_valid = true;
|
||||
});
|
||||
|
||||
memgraph::license::LicenseInfoSender license_sender(FLAGS_endpoint, memgraph::utils::GenerateUUID(),
|
||||
memgraph::utils::GetMachineId(), 10000000, license_info,
|
||||
std::chrono::seconds(FLAGS_interval));
|
||||
std::this_thread::sleep_for(std::chrono::seconds(FLAGS_duration));
|
||||
|
||||
return 0;
|
||||
}
|
96
tests/integration/license_info/runner.py
Executable file
96
tests/integration/license_info/runner.py
Executable file
@ -0,0 +1,96 @@
|
||||
#!/usr/bin/python3 -u
|
||||
|
||||
# Copyright 2021 Memgraph Ltd.
|
||||
#
|
||||
# Use of this software is governed by the Business Source License
|
||||
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
# License, and you may not use this file except in compliance with the Business Source License.
|
||||
#
|
||||
# As of the Change Date specified in that file, in accordance with
|
||||
# the Business Source License, use of this software will be governed
|
||||
# by the Apache License, Version 2.0, included in the file
|
||||
# licenses/APL.txt.
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
PROJECT_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, "..", "..", ".."))
|
||||
|
||||
|
||||
def execute_test(**kwargs):
|
||||
client_binary = kwargs.pop("client")
|
||||
server_binary = kwargs.pop("server")
|
||||
|
||||
start_server = kwargs.pop("start_server", True)
|
||||
interval = kwargs.pop("interval", 1)
|
||||
duration = kwargs.pop("duration", 5)
|
||||
license_type = kwargs.pop("license-type", "enterprise")
|
||||
|
||||
timeout = duration * 2 if "hang" not in kwargs else duration * 2 + 60
|
||||
success = False
|
||||
|
||||
client_args = [client_binary, "--interval", interval, "--duration", duration, "--license-type", license_type]
|
||||
|
||||
server = None
|
||||
if start_server:
|
||||
server = subprocess.Popen(server_binary)
|
||||
time.sleep(0.4)
|
||||
assert server.poll() is None, "Server process died prematurely!"
|
||||
|
||||
try:
|
||||
subprocess.run(list(map(str, client_args)), timeout=timeout, check=True)
|
||||
finally:
|
||||
if server is None:
|
||||
success = True
|
||||
else:
|
||||
server.terminate()
|
||||
try:
|
||||
success = server.wait(timeout=5) == 0
|
||||
success = True
|
||||
except subprocess.TimeoutExpired:
|
||||
server.kill()
|
||||
return success
|
||||
|
||||
|
||||
def main():
|
||||
server_binary = os.path.join(SCRIPT_DIR, "server.py")
|
||||
client_binary = os.path.join(PROJECT_DIR, "build", "tests", "integration", "license_info", "client")
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--client", default=client_binary)
|
||||
parser.add_argument("--server", default=server_binary)
|
||||
parser.add_argument("--server-url", default="127.0.0.1")
|
||||
parser.add_argument("--server-port", default="5500")
|
||||
args = parser.parse_args()
|
||||
|
||||
tests = [
|
||||
{"interval": 2},
|
||||
{"duration": 10},
|
||||
{"interval": 2, "duration": 10},
|
||||
{"license-type": "oem"},
|
||||
{"license-type": "enterprise"},
|
||||
]
|
||||
for test in tests:
|
||||
print("\033[1;36m~~ Executing test with arguments:", json.dumps(test, sort_keys=True), "~~\033[0m")
|
||||
|
||||
try:
|
||||
success = execute_test(client=args.client, server=args.server, **test)
|
||||
except Exception as e:
|
||||
print("\033[1;33m", e, "\033[0m", sep="")
|
||||
success = False
|
||||
|
||||
if not success:
|
||||
print("\033[1;31m~~", "Test failed!", "~~\033[0m")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("\033[1;32m~~", "Test ok!", "~~\033[0m")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
69
tests/integration/license_info/server.py
Executable file
69
tests/integration/license_info/server.py
Executable file
@ -0,0 +1,69 @@
|
||||
#!/usr/bin/python3 -u
|
||||
|
||||
# Copyright 2021 Memgraph Ltd.
|
||||
#
|
||||
# Use of this software is governed by the Business Source License
|
||||
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
# License, and you may not use this file except in compliance with the Business Source License.
|
||||
#
|
||||
# As of the Change Date specified in that file, in accordance with
|
||||
# the Business Source License, use of this software will be governed
|
||||
# by the Apache License, Version 2.0, included in the file
|
||||
# licenses/APL.txt.
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
||||
|
||||
EXPECTED_LICENSE_INFO_FIELDS = {
|
||||
"run_id": str,
|
||||
"machine_id": str,
|
||||
"type": str,
|
||||
"license_type": str,
|
||||
"license_key": str,
|
||||
"organization": str,
|
||||
"valid": bool,
|
||||
"physical_memory_size": int,
|
||||
"swap_memory_size": int,
|
||||
"memory_used": int,
|
||||
"runtime_memory_limit": int,
|
||||
"license_memory_limit": int,
|
||||
"timestamp": float,
|
||||
}
|
||||
|
||||
|
||||
class ServerHandler(SimpleHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
assert self.headers["user-agent"] == "memgraph/license-info", f"The header is {self.headers['user-agent']}"
|
||||
assert self.headers["accept"] == "application/json", f"The header is {self.headers['accept']}"
|
||||
assert self.headers["content-type"] == "application/json", f"The header is {self.headers['content-type']}"
|
||||
|
||||
content_len = int(self.headers.get("content-length", 0))
|
||||
data = json.loads(self.rfile.read(content_len).decode("utf-8"))
|
||||
|
||||
assert isinstance(data, dict)
|
||||
|
||||
for expected_field, expected_type in EXPECTED_LICENSE_INFO_FIELDS.items():
|
||||
assert expected_field in data, f"Field {expected_field} not found in received data"
|
||||
assert isinstance(
|
||||
data[expected_field], expected_type
|
||||
), f"Field {expected_field} is not correct type: expected {expected_type} got {type(data[expected_field])}"
|
||||
assert len(EXPECTED_LICENSE_INFO_FIELDS) == len(data), "Expected data size does not match received"
|
||||
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--address", type=str, default="127.0.0.1")
|
||||
parser.add_argument("--port", type=int, default=5500)
|
||||
args = parser.parse_args()
|
||||
|
||||
with HTTPServer((args.address, args.port), ServerHandler) as srv:
|
||||
print(f"Serving HTTP server at {args.address}:{args.port}")
|
||||
srv.serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -3,4 +3,4 @@ set(client_target_name ${target_name}__client)
|
||||
|
||||
add_executable(${client_target_name} client.cpp)
|
||||
set_target_properties(${client_target_name} PROPERTIES OUTPUT_NAME client)
|
||||
target_link_libraries(${client_target_name} mg-requests telemetry_lib)
|
||||
target_link_libraries(${client_target_name} mg-requests mg-telemetry)
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include "requests/requests.hpp"
|
||||
#include "telemetry/telemetry.hpp"
|
||||
#include "utils/system_info.hpp"
|
||||
#include "utils/uuid.hpp"
|
||||
|
||||
DEFINE_string(endpoint, "http://127.0.0.1:9000/", "Endpoint that should be used for the test.");
|
||||
DEFINE_int64(interval, 1, "Interval used for reporting telemetry in seconds.");
|
||||
@ -24,8 +26,8 @@ int main(int argc, char **argv) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
memgraph::requests::Init();
|
||||
memgraph::telemetry::Telemetry telemetry(FLAGS_endpoint, FLAGS_storage_directory,
|
||||
std::chrono::seconds(FLAGS_interval), 1);
|
||||
memgraph::telemetry::Telemetry telemetry(FLAGS_endpoint, FLAGS_storage_directory, memgraph::utils::GenerateUUID(),
|
||||
memgraph::utils::GetMachineId(), std::chrono::seconds(FLAGS_interval), 1);
|
||||
|
||||
uint64_t counter = 0;
|
||||
telemetry.AddCollector("db", [&counter]() -> nlohmann::json {
|
||||
|
@ -36,8 +36,7 @@ def execute_test(**kwargs):
|
||||
timeout = duration * 2 if "hang" not in kwargs else duration * 2 + 60
|
||||
success = False
|
||||
|
||||
server_args = [server_binary, "--interval", interval,
|
||||
"--duration", duration]
|
||||
server_args = [server_binary, "--interval", interval, "--duration", duration]
|
||||
for flag, value in kwargs.items():
|
||||
flag = "--" + flag.replace("_", "-")
|
||||
# We handle boolean flags here. The type of value must be `bool`, and
|
||||
@ -48,9 +47,15 @@ def execute_test(**kwargs):
|
||||
else:
|
||||
server_args.extend([flag, value])
|
||||
|
||||
client_args = [client_binary, "--interval", interval,
|
||||
"--duration", duration,
|
||||
"--storage-directory", storage_directory]
|
||||
client_args = [
|
||||
client_binary,
|
||||
"--interval",
|
||||
interval,
|
||||
"--duration",
|
||||
duration,
|
||||
"--storage-directory",
|
||||
storage_directory,
|
||||
]
|
||||
if endpoint:
|
||||
client_args.extend(["--endpoint", endpoint])
|
||||
|
||||
@ -61,8 +66,7 @@ def execute_test(**kwargs):
|
||||
assert server.poll() is None, "Server process died prematurely!"
|
||||
|
||||
try:
|
||||
subprocess.run(list(map(str, client_args)), timeout=timeout,
|
||||
check=True)
|
||||
subprocess.run(list(map(str, client_args)), timeout=timeout, check=True)
|
||||
finally:
|
||||
if server is None:
|
||||
success = True
|
||||
@ -88,16 +92,14 @@ TESTS = [
|
||||
{"endpoint": "http://127.0.0.1:9000/nonexistant/", "no_check": True},
|
||||
{"start_server": False},
|
||||
{"startups": 4, "no_check_duration": True}, # the last 3 tests failed
|
||||
# to send any data + this test
|
||||
{"add_garbage": True}
|
||||
# to send any data + this test
|
||||
{"add_garbage": True},
|
||||
]
|
||||
|
||||
if __name__ == "__main__":
|
||||
server_binary = os.path.join(SCRIPT_DIR, "server.py")
|
||||
client_binary = os.path.join(PROJECT_DIR, "build", "tests",
|
||||
"integration", "telemetry", "client")
|
||||
kvstore_console_binary = os.path.join(PROJECT_DIR, "build", "tests",
|
||||
"manual", "kvstore_console")
|
||||
client_binary = os.path.join(PROJECT_DIR, "build", "tests", "integration", "telemetry", "client")
|
||||
kvstore_console_binary = os.path.join(PROJECT_DIR, "build", "tests", "manual", "kvstore_console")
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--client", default=client_binary)
|
||||
@ -108,19 +110,17 @@ if __name__ == "__main__":
|
||||
storage = tempfile.TemporaryDirectory()
|
||||
|
||||
for test in TESTS:
|
||||
print("\033[1;36m~~ Executing test with arguments:",
|
||||
json.dumps(test, sort_keys=True), "~~\033[0m")
|
||||
print("\033[1;36m~~ Executing test with arguments:", json.dumps(test, sort_keys=True), "~~\033[0m")
|
||||
|
||||
if test.pop("add_garbage", False):
|
||||
proc = subprocess.Popen([args.kvstore_console, "--path",
|
||||
storage.name], stdin=subprocess.PIPE,
|
||||
stdout=subprocess.DEVNULL)
|
||||
proc = subprocess.Popen(
|
||||
[args.kvstore_console, "--path", storage.name], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL
|
||||
)
|
||||
proc.communicate("put garbage garbage".encode("utf-8"))
|
||||
assert proc.wait() == 0
|
||||
|
||||
try:
|
||||
success = execute_test(client=args.client, server=args.server,
|
||||
storage=storage.name, **test)
|
||||
success = execute_test(client=args.client, server=args.server, storage=storage.name, **test)
|
||||
except Exception as e:
|
||||
print("\033[1;33m", e, "\033[0m", sep="")
|
||||
success = False
|
||||
|
@ -12,13 +12,12 @@
|
||||
# licenses/APL.txt.
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import json
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
import time
|
||||
import itertools
|
||||
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
|
||||
|
||||
@ -46,7 +45,7 @@ def build_handler(storage, args):
|
||||
assert self.headers["accept"] == "application/json"
|
||||
assert self.headers["content-type"] == "application/json"
|
||||
|
||||
content_len = int(self.headers.get('content-length', 0))
|
||||
content_len = int(self.headers.get("content-length", 0))
|
||||
data = json.loads(self.rfile.read(content_len).decode("utf-8"))
|
||||
|
||||
if self.path not in [args.path, args.redirect_path]:
|
||||
@ -70,6 +69,7 @@ def build_handler(storage, args):
|
||||
assert type(item) == dict
|
||||
assert "event" in item
|
||||
assert "run_id" in item
|
||||
assert "type" in item
|
||||
assert "machine_id" in item
|
||||
assert "data" in item
|
||||
assert "timestamp" in item
|
||||
@ -188,11 +188,11 @@ if __name__ == "__main__":
|
||||
startups[-1].append(item)
|
||||
|
||||
# Check that there were the correct number of startups.
|
||||
assert len(startups) == args.startups
|
||||
assert len(startups) == args.startups, f"Expected: {args.startups}, actual: {len(startups)}"
|
||||
|
||||
# Verify each startup.
|
||||
for startup in startups:
|
||||
verify_storage(startup, args)
|
||||
|
||||
# machine id has to be same for every run on the same machine
|
||||
assert len(set(map(lambda x: x['machine_id'], itertools.chain(*startups)))) == 1
|
||||
assert len(set(map(lambda x: x["machine_id"], itertools.chain(*startups)))) == 1
|
||||
|
@ -10,11 +10,11 @@
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "query/config.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "storage/v2/isolation_level.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/on_scope_exit.hpp"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@ -30,7 +30,7 @@ int main(int argc, char *argv[]) {
|
||||
auto data_directory = std::filesystem::temp_directory_path() / "single_query_test";
|
||||
memgraph::utils::OnScopeExit([&data_directory] { std::filesystem::remove_all(data_directory); });
|
||||
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
memgraph::query::InterpreterContext interpreter_context{&db, memgraph::query::InterpreterConfig{}, data_directory};
|
||||
memgraph::query::Interpreter interpreter{&interpreter_context};
|
||||
|
||||
|
@ -269,8 +269,8 @@ target_link_libraries(${test_prefix}utils_csv_parsing mg-utils fmt)
|
||||
add_unit_test(utils_async_timer.cpp)
|
||||
target_link_libraries(${test_prefix}utils_async_timer mg-utils)
|
||||
|
||||
add_unit_test(utils_license.cpp)
|
||||
target_link_libraries(${test_prefix}utils_license mg-utils mg-license)
|
||||
add_unit_test(license.cpp)
|
||||
target_link_libraries(${test_prefix}license mg-utils mg-license)
|
||||
|
||||
add_unit_test(utils_settings.cpp)
|
||||
target_link_libraries(${test_prefix}utils_settings mg-utils mg-settings)
|
||||
|
@ -19,9 +19,9 @@
|
||||
#include "auth/auth.hpp"
|
||||
#include "auth/crypto.hpp"
|
||||
#include "auth/models.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "utils/cast.hpp"
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/license.hpp"
|
||||
|
||||
using namespace memgraph::auth;
|
||||
namespace fs = std::filesystem;
|
||||
@ -36,7 +36,7 @@ class AuthWithStorage : public ::testing::Test {
|
||||
FLAGS_auth_password_permit_null = true;
|
||||
FLAGS_auth_password_strength_regex = ".+";
|
||||
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
}
|
||||
|
||||
virtual void TearDown() { fs::remove_all(test_folder_); }
|
||||
|
@ -15,9 +15,9 @@
|
||||
#include "auth/models.hpp"
|
||||
#include "glue/auth_checker.hpp"
|
||||
|
||||
#include "license/license.hpp"
|
||||
#include "query_plan_common.hpp"
|
||||
#include "storage/v2/view.hpp"
|
||||
#include "utils/license.hpp"
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
class FineGrainedAuthCheckerFixture : public testing::Test {
|
||||
@ -39,7 +39,7 @@ class FineGrainedAuthCheckerFixture : public testing::Test {
|
||||
memgraph::query::EdgeAccessor r4{*dba.InsertEdge(&v1, &v3, edge_type_two)};
|
||||
|
||||
void SetUp() override {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
|
||||
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
|
||||
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
|
||||
|
@ -37,7 +37,7 @@ class AuthQueryHandlerFixture : public testing::Test {
|
||||
#endif
|
||||
virtual void SetUp() {
|
||||
memgraph::utils::EnsureDir(test_folder_);
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <gtest/internal/gtest-param-util-generated.h>
|
||||
|
||||
#include "auth/models.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "license/license.hpp"
|
||||
|
||||
using namespace memgraph::query;
|
||||
using namespace memgraph::query::plan;
|
||||
@ -80,7 +80,7 @@ class FineGrainedBfsTest
|
||||
std::tuple<int, int, EdgeAtom::Direction, std::vector<std::string>, bool, FineGrainedTestType>> {
|
||||
public:
|
||||
static void SetUpTestCase() {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
db_ = std::make_unique<VertexDb>();
|
||||
}
|
||||
static void TearDownTestCase() { db_ = nullptr; }
|
||||
|
@ -480,6 +480,39 @@ TEST_F(InterpreterTest, ShortestPath) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(InterpreterTest, AllShortestById) {
|
||||
auto stream_init = Interpret(
|
||||
"CREATE (n:A {x: 1}), (m:B {x: 2}), (l:C {x: 3}), (k:D {x: 4}), (n)-[:r1 {w: 1 "
|
||||
"}]->(m)-[:r2 {w: 2}]->(l), (n)-[:r3 {w: 4}]->(l), (k)-[:r4 {w: 3}]->(l) return id(n), id(l)");
|
||||
|
||||
auto id_n = stream_init.GetResults().front()[0].ValueInt();
|
||||
auto id_l = stream_init.GetResults().front()[1].ValueInt();
|
||||
|
||||
auto stream = Interpret(
|
||||
fmt::format("MATCH (n)-[e *allshortest 5 (e, n | e.w) ]->(l) WHERE id(n)={} AND id(l)={} return e", id_n, id_l));
|
||||
|
||||
ASSERT_EQ(stream.GetHeader().size(), 1U);
|
||||
EXPECT_EQ(stream.GetHeader()[0], "e");
|
||||
ASSERT_EQ(stream.GetResults().size(), 1U);
|
||||
|
||||
auto dba = db_.Access();
|
||||
std::vector<std::string> expected_result = {"r1", "r2"};
|
||||
|
||||
const auto &result = stream.GetResults()[0];
|
||||
const auto &edges = ToEdgeList(result[0]);
|
||||
|
||||
std::vector<std::string> datum;
|
||||
datum.reserve(edges.size());
|
||||
|
||||
for (const auto &edge : edges) {
|
||||
datum.push_back(edge.type);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(expected_result == datum);
|
||||
|
||||
Interpret("MATCH (n) DETACH DELETE n");
|
||||
}
|
||||
|
||||
TEST_F(InterpreterTest, CreateLabelIndexInMulticommandTransaction) {
|
||||
Interpret("BEGIN");
|
||||
ASSERT_THROW(Interpret("CREATE INDEX ON :X"), memgraph::query::IndexInMulticommandTxException);
|
||||
|
@ -10,8 +10,9 @@
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstdint>
|
||||
|
||||
#include "utils/license.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "utils/settings.hpp"
|
||||
|
||||
class LicenseTest : public ::testing::Test {
|
||||
@ -21,7 +22,7 @@ class LicenseTest : public ::testing::Test {
|
||||
settings->Initialize(settings_directory);
|
||||
|
||||
license_checker.emplace();
|
||||
memgraph::utils::license::RegisterLicenseSettings(*license_checker, *settings);
|
||||
memgraph::license::RegisterLicenseSettings(*license_checker, *settings);
|
||||
|
||||
license_checker->StartBackgroundLicenseChecker(*settings);
|
||||
}
|
||||
@ -33,24 +34,25 @@ class LicenseTest : public ::testing::Test {
|
||||
const std::filesystem::path settings_directory{test_directory / "settings"};
|
||||
|
||||
void CheckLicenseValidity(const bool expected_valid) {
|
||||
ASSERT_EQ(!license_checker->IsValidLicense(*settings).HasError(), expected_valid);
|
||||
ASSERT_EQ(license_checker->IsValidLicenseFast(), expected_valid);
|
||||
ASSERT_EQ(!license_checker->IsEnterpriseValid(*settings).HasError(), expected_valid);
|
||||
ASSERT_EQ(license_checker->IsEnterpriseValidFast(), expected_valid);
|
||||
}
|
||||
|
||||
std::optional<memgraph::utils::Settings> settings;
|
||||
std::optional<memgraph::utils::license::LicenseChecker> license_checker;
|
||||
std::optional<memgraph::license::LicenseChecker> license_checker;
|
||||
};
|
||||
|
||||
TEST_F(LicenseTest, EncodeDecode) {
|
||||
const std::array licenses = {
|
||||
memgraph::utils::license::License{"Organization", 1, 2},
|
||||
memgraph::utils::license::License{"", -1, 0},
|
||||
memgraph::utils::license::License{"Some very long name for the organization Ltd", -999, -9999},
|
||||
memgraph::license::License{"Organization", 1, 2, memgraph::license::LicenseType::OEM},
|
||||
memgraph::license::License{"", -1, 0, memgraph::license::LicenseType::ENTERPRISE},
|
||||
memgraph::license::License{"Some very long name for the organization Ltd", -999, -9999,
|
||||
memgraph::license::LicenseType::ENTERPRISE},
|
||||
};
|
||||
|
||||
for (const auto &license : licenses) {
|
||||
const auto result = memgraph::utils::license::Encode(license);
|
||||
auto maybe_license = memgraph::utils::license::Decode(result);
|
||||
const auto result = memgraph::license::Encode(license);
|
||||
auto maybe_license = memgraph::license::Decode(result);
|
||||
ASSERT_TRUE(maybe_license);
|
||||
ASSERT_EQ(*maybe_license, license);
|
||||
}
|
||||
@ -69,10 +71,9 @@ TEST_F(LicenseTest, TestingFlag) {
|
||||
|
||||
TEST_F(LicenseTest, LicenseOrganizationName) {
|
||||
const std::string organization_name{"Memgraph"};
|
||||
memgraph::utils::license::License license{
|
||||
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0};
|
||||
memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
|
||||
|
||||
settings->SetValue("enterprise.license", memgraph::utils::license::Encode(license));
|
||||
settings->SetValue("enterprise.license", memgraph::license::Encode(license));
|
||||
settings->SetValue("organization.name", organization_name);
|
||||
CheckLicenseValidity(true);
|
||||
|
||||
@ -91,22 +92,21 @@ TEST_F(LicenseTest, Expiration) {
|
||||
std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
const auto delta = std::chrono::seconds(1);
|
||||
const auto valid_until = now + delta;
|
||||
memgraph::utils::license::License license{
|
||||
.organization_name = organization_name, .valid_until = valid_until.count(), .memory_limit = 0};
|
||||
memgraph::license::License license{organization_name, valid_until.count(), 0,
|
||||
memgraph::license::LicenseType::ENTERPRISE};
|
||||
|
||||
settings->SetValue("enterprise.license", memgraph::utils::license::Encode(license));
|
||||
settings->SetValue("enterprise.license", memgraph::license::Encode(license));
|
||||
settings->SetValue("organization.name", organization_name);
|
||||
CheckLicenseValidity(true);
|
||||
|
||||
std::this_thread::sleep_for(delta + std::chrono::seconds(1));
|
||||
ASSERT_TRUE(license_checker->IsValidLicense(*settings).HasError());
|
||||
ASSERT_TRUE(license_checker->IsEnterpriseValid(*settings).HasError());
|
||||
// We can't check fast checker because it has unknown refresh rate
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("License with valid_until = 0 is always valid");
|
||||
memgraph::utils::license::License license{
|
||||
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0};
|
||||
settings->SetValue("enterprise.license", memgraph::utils::license::Encode(license));
|
||||
memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
|
||||
settings->SetValue("enterprise.license", memgraph::license::Encode(license));
|
||||
settings->SetValue("organization.name", organization_name);
|
||||
CheckLicenseValidity(true);
|
||||
}
|
||||
@ -116,9 +116,8 @@ TEST_F(LicenseTest, LicenseInfoOverride) {
|
||||
CheckLicenseValidity(false);
|
||||
|
||||
const std::string organization_name{"Memgraph"};
|
||||
memgraph::utils::license::License license{
|
||||
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0};
|
||||
const std::string license_key = memgraph::utils::license::Encode(license);
|
||||
memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
|
||||
const std::string license_key = memgraph::license::Encode(license);
|
||||
|
||||
{
|
||||
SCOPED_TRACE("Checker should use overrides instead of info from the settings");
|
||||
@ -139,3 +138,40 @@ TEST_F(LicenseTest, LicenseInfoOverride) {
|
||||
CheckLicenseValidity(false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(LicenseTest, LicenseType) {
|
||||
CheckLicenseValidity(false);
|
||||
const std::string organization_name{"Memgraph"};
|
||||
{
|
||||
memgraph::license::License license_entr{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
|
||||
const std::string license_key = memgraph::license::Encode(license_entr);
|
||||
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||
CheckLicenseValidity(true);
|
||||
}
|
||||
{
|
||||
memgraph::license::License license_oem{organization_name, 0, 0, memgraph::license::LicenseType::OEM};
|
||||
const std::string license_key = memgraph::license::Encode(license_oem);
|
||||
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||
CheckLicenseValidity(false);
|
||||
}
|
||||
{
|
||||
memgraph::license::License license_oem{organization_name, 0, 0, memgraph::license::LicenseType::OEM};
|
||||
const std::string license_key = memgraph::license::Encode(license_oem);
|
||||
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||
CheckLicenseValidity(false);
|
||||
}
|
||||
{
|
||||
memgraph::license::License license_oem{organization_name, std::numeric_limits<int64_t>::min(),
|
||||
std::numeric_limits<int64_t>::max(), memgraph::license::LicenseType::OEM};
|
||||
const std::string license_key = memgraph::license::Encode(license_oem);
|
||||
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||
CheckLicenseValidity(false);
|
||||
}
|
||||
{
|
||||
memgraph::license::License license_oem{organization_name, std::numeric_limits<int64_t>::max(),
|
||||
std::numeric_limits<int64_t>::min(), memgraph::license::LicenseType::OEM};
|
||||
const std::string license_key = memgraph::license::Encode(license_oem);
|
||||
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||
CheckLicenseValidity(false);
|
||||
}
|
||||
}
|
@ -20,11 +20,11 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "license/license.hpp"
|
||||
#include "query/context.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
#include "query/interpret/frame.hpp"
|
||||
#include "query/plan/operator.hpp"
|
||||
#include "utils/license.hpp"
|
||||
|
||||
#include "query_plan_common.hpp"
|
||||
#include "storage/v2/id_types.hpp"
|
||||
@ -80,7 +80,7 @@ TEST(QueryPlan, CreateNodeWithAttributes) {
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
TEST(QueryPlan, FineGrainedCreateNodeWithAttributes) {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
memgraph::query::AstStorage ast;
|
||||
memgraph::query::SymbolTable symbol_table;
|
||||
memgraph::storage::Storage db;
|
||||
@ -164,7 +164,7 @@ TEST(QueryPlan, CreateReturn) {
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
TEST(QueryPlan, FineGrainedCreateReturn) {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
|
||||
// test CREATE (n:Person {age: 42}) RETURN n, n.age
|
||||
memgraph::storage::Storage db;
|
||||
@ -310,7 +310,7 @@ class CreateExpandWithAuthFixture : public testing::Test {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
||||
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||
|
||||
void ExecuteCreateExpand(bool cycle, memgraph::auth::User &user) {
|
||||
const auto label_node_1 = dba.NameToLabel("Node1");
|
||||
@ -470,7 +470,7 @@ class MatchCreateNodeWithAuthFixture : public testing::Test {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
||||
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||
|
||||
void InitGraph() {
|
||||
// add three nodes we'll match and expand-create from
|
||||
@ -600,7 +600,7 @@ class MatchCreateExpandWithAuthFixture : public testing::Test {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
||||
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||
|
||||
void InitGraph() {
|
||||
// add three nodes we'll match and expand-create from
|
||||
@ -818,7 +818,7 @@ class DeleteOperatorWithAuthFixture : public testing::Test {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
||||
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||
|
||||
void InitGraph() {
|
||||
std::vector<memgraph::query::VertexAccessor> vertices;
|
||||
@ -1253,7 +1253,7 @@ TEST(QueryPlan, SetLabels) {
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
TEST(QueryPlan, SetLabelsWithFineGrained) {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
auto set_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba,
|
||||
std::vector<memgraph::storage::LabelId> labels) {
|
||||
ASSERT_TRUE(dba.InsertVertex().AddLabel(labels[0]).HasValue());
|
||||
@ -1426,7 +1426,7 @@ TEST(QueryPlan, RemoveLabels) {
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
TEST(QueryPlan, RemoveLabelsFineGrainedFiltering) {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
auto remove_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba,
|
||||
std::vector<memgraph::storage::LabelId> labels) {
|
||||
auto v1 = dba.InsertVertex();
|
||||
@ -1896,7 +1896,7 @@ class UpdatePropertiesWithAuthFixture : public testing::Test {
|
||||
const memgraph::storage::PropertyId edge_prop{dba.NameToProperty(edge_prop_name)};
|
||||
const memgraph::storage::PropertyValue edge_prop_value{1};
|
||||
|
||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
||||
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||
|
||||
void SetVertexProperty(memgraph::query::VertexAccessor vertex) {
|
||||
static_cast<void>(vertex.SetProperty(entity_prop, entity_prop_value));
|
||||
|
@ -30,10 +30,10 @@
|
||||
#include "auth/auth.hpp"
|
||||
#include "auth/models.hpp"
|
||||
#include "glue/auth_checker.hpp"
|
||||
#include "license/license.hpp"
|
||||
#include "query/context.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
#include "query/plan/operator.hpp"
|
||||
#include "utils/license.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
|
||||
using namespace memgraph::query;
|
||||
@ -50,7 +50,7 @@ class MatchReturnFixture : public testing::Test {
|
||||
void AddVertices(int count) {
|
||||
for (int i = 0; i < count; i++) dba.InsertVertex();
|
||||
}
|
||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
||||
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||
|
||||
std::vector<Path> PathResults(std::shared_ptr<Produce> &op) {
|
||||
std::vector<Path> res;
|
||||
@ -485,7 +485,7 @@ class ExpandFixture : public testing::Test {
|
||||
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
|
||||
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
|
||||
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
|
||||
dba.AdvanceCommand();
|
||||
}
|
||||
@ -628,7 +628,7 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
std::nullopt_t nullopt = std::nullopt;
|
||||
|
||||
void SetUp() {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
|
||||
// create the graph
|
||||
int chain_length = 3;
|
||||
@ -1778,7 +1778,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
|
||||
Symbol total_weight = symbol_table.CreateSymbol("total_weight", true);
|
||||
|
||||
void SetUp() {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
v.push_back(dba.InsertVertex());
|
||||
@ -2208,7 +2208,7 @@ class QueryPlanExpandAllShortestPaths : public testing::Test {
|
||||
Symbol total_weight = symbol_table.CreateSymbol("total_weight", true);
|
||||
|
||||
void SetUp() {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
v.push_back(dba.InsertVertex());
|
||||
|
@ -13,11 +13,11 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "license/license.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/ast/ast_visitor.hpp"
|
||||
#include "query/frontend/semantic/required_privileges.hpp"
|
||||
#include "storage/v2/id_types.hpp"
|
||||
#include "utils/license.hpp"
|
||||
|
||||
#include "query_common.hpp"
|
||||
|
||||
@ -100,7 +100,7 @@ TEST_F(TestPrivilegeExtractor, CreateIndex) {
|
||||
}
|
||||
#ifdef MG_ENTERPRISE
|
||||
TEST_F(TestPrivilegeExtractor, AuthQuery) {
|
||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
||||
memgraph::license::global_license_checker.EnableTesting();
|
||||
auto label_privileges = std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{};
|
||||
auto edge_type_privileges =
|
||||
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{};
|
||||
|
Loading…
Reference in New Issue
Block a user