Merge branch 'master' into release/2.4

This commit is contained in:
jbajic 2022-11-07 13:17:29 +01:00
commit 64e3aff65b
50 changed files with 1094 additions and 420 deletions

98
environment/os/fedora-36.sh Executable file
View 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
View File

@ -0,0 +1 @@
*.tar.gz

View File

@ -10,6 +10,14 @@ cd "$DIR"
source "$DIR/../util.sh" source "$DIR/../util.sh"
DISTRO="$(operating_system)" DISTRO="$(operating_system)"
function log_tool_name () {
echo ""
echo ""
echo "#### $1 ####"
echo ""
echo ""
}
for_arm=false for_arm=false
if [[ "$#" -eq 1 ]]; then if [[ "$#" -eq 1 ]]; then
if [[ "$1" == "--for-arm" ]]; then if [[ "$1" == "--for-arm" ]]; then
@ -20,9 +28,11 @@ if [[ "$#" -eq 1 ]]; then
fi fi
fi fi
os="$1" TOOLCHAIN_STDCXX="${TOOLCHAIN_STDCXX:-libstdc++}"
if [[ "$TOOLCHAIN_STDCXX" != "libstdc++" && "$TOOLCHAIN_STDCXX" != "libc++" ]]; then
# toolchain version echo "Only GCC (libstdc++) or LLVM (libc++) C++ standard library implementations are supported."
exit 1
fi
TOOLCHAIN_VERSION=4 TOOLCHAIN_VERSION=4
# package versions used # 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/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/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/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 fi
if [ ! -f pahole-gdb-master.zip ]; then if [ ! -f pahole-gdb-master.zip ]; then
wget https://github.com/PhilArmstrong/pahole-gdb/archive/master.zip -O pahole-gdb-master.zip 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/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/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/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 fi
# list of valid llvm gnupg keys: https://releases.llvm.org/download.html # list of valid llvm gnupg keys: https://releases.llvm.org/download.html
$GPG --keyserver $KEYSERVER --recv-keys 0x474E22316ABF4785A88C6E8EA2C794A986419D8A $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 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 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 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 popd
@ -172,7 +188,7 @@ popd
mkdir -p build mkdir -p build
pushd build pushd build
# compile gcc log_tool_name "GCC $GCC_VERSION"
if [ ! -f $PREFIX/bin/gcc ]; then if [ ! -f $PREFIX/bin/gcc ]; then
if [ -d gcc-$GCC_VERSION ]; then if [ -d gcc-$GCC_VERSION ]; then
rm -rf gcc-$GCC_VERSION rm -rf gcc-$GCC_VERSION
@ -263,7 +279,7 @@ fi
export PATH=$PREFIX/bin:$PATH export PATH=$PREFIX/bin:$PATH
export LD_LIBRARY_PATH=$PREFIX/lib64 export LD_LIBRARY_PATH=$PREFIX/lib64
# compile binutils log_tool_name "binutils $BINUTILS_VERSION"
if [ ! -f $PREFIX/bin/ld.gold ]; then if [ ! -f $PREFIX/bin/ld.gold ]; then
if [ -d binutils-$BINUTILS_VERSION ]; then if [ -d binutils-$BINUTILS_VERSION ]; then
rm -rf binutils-$BINUTILS_VERSION rm -rf binutils-$BINUTILS_VERSION
@ -327,7 +343,7 @@ if [ ! -f $PREFIX/bin/ld.gold ]; then
popd && popd popd && popd
fi fi
# compile gdb log_tool_name "GDB $GDB_VERSION"
if [ ! -f $PREFIX/bin/gdb ]; then if [ ! -f $PREFIX/bin/gdb ]; then
if [ -d gdb-$GDB_VERSION ]; then if [ -d gdb-$GDB_VERSION ]; then
rm -rf gdb-$GDB_VERSION rm -rf gdb-$GDB_VERSION
@ -398,13 +414,13 @@ if [ ! -f $PREFIX/bin/gdb ]; then
popd && popd popd && popd
fi fi
# install pahole log_tool_name "install pahole"
if [ ! -d $PREFIX/share/pahole-gdb ]; then if [ ! -d $PREFIX/share/pahole-gdb ]; then
unzip ../archives/pahole-gdb-master.zip unzip ../archives/pahole-gdb-master.zip
mv pahole-gdb-master $PREFIX/share/pahole-gdb mv pahole-gdb-master $PREFIX/share/pahole-gdb
fi fi
# setup system gdbinit log_tool_name "setup system gdbinit"
if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then
mkdir -p $PREFIX/etc/gdb mkdir -p $PREFIX/etc/gdb
cat >$PREFIX/etc/gdb/gdbinit <<EOF cat >$PREFIX/etc/gdb/gdbinit <<EOF
@ -430,7 +446,7 @@ end
EOF EOF
fi fi
# compile cmake log_tool_name "cmake $CMAKE_VERSION"
if [ ! -f $PREFIX/bin/cmake ]; then if [ ! -f $PREFIX/bin/cmake ]; then
if [ -d cmake-$CMAKE_VERSION ]; then if [ -d cmake-$CMAKE_VERSION ]; then
rm -rf cmake-$CMAKE_VERSION rm -rf cmake-$CMAKE_VERSION
@ -456,7 +472,7 @@ if [ ! -f $PREFIX/bin/cmake ]; then
popd && popd popd && popd
fi fi
# compile cppcheck log_tool_name "cppcheck $CPPCHECK_VERSION"
if [ ! -f $PREFIX/bin/cppcheck ]; then if [ ! -f $PREFIX/bin/cppcheck ]; then
if [ -d cppcheck-$CPPCHECK_VERSION ]; then if [ -d cppcheck-$CPPCHECK_VERSION ]; then
rm -rf cppcheck-$CPPCHECK_VERSION rm -rf cppcheck-$CPPCHECK_VERSION
@ -480,7 +496,7 @@ if [ ! -f $PREFIX/bin/cppcheck ]; then
popd popd
fi fi
# compile swig log_tool_name "swig $SWIG_VERSION"
if [ ! -d swig-$SWIG_VERSION/install ]; then if [ ! -d swig-$SWIG_VERSION/install ]; then
if [ -d swig-$SWIG_VERSION ]; then if [ -d swig-$SWIG_VERSION ]; then
rm -rf swig-$SWIG_VERSION rm -rf swig-$SWIG_VERSION
@ -496,7 +512,7 @@ if [ ! -d swig-$SWIG_VERSION/install ]; then
popd && popd popd && popd
fi fi
# compile llvm log_tool_name "LLVM $LLVM_VERSION"
if [ ! -f $PREFIX/bin/clang ]; then if [ ! -f $PREFIX/bin/clang ]; then
if [ -d llvm-$LLVM_VERSION ]; then if [ -d llvm-$LLVM_VERSION ]; then
rm -rf llvm-$LLVM_VERSION 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 mv compiler-rt-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/projects/compiler-rt
tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz
mv libunwind-$LLVM_VERSION.src/include/mach-o llvm-$LLVM_VERSION/tools/lld/include 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 pushd llvm-$LLVM_VERSION
mkdir build && pushd build mkdir -p build && pushd build
# activate swig # activate swig
export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH 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 # 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 CC=$PREFIX/bin/clang
export CXX=$PREFIX/bin/clang++ export CXX=$PREFIX/bin/clang++
export CFLAGS="$CFLAGS -fPIC" 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 COMMON_CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$PREFIX
-DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_PREFIX_PATH=$PREFIX
-DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_TYPE=Release
@ -834,7 +865,7 @@ COMMON_CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$PREFIX
COMMON_CONFIGURE_FLAGS="--enable-shared=no --prefix=$PREFIX" COMMON_CONFIGURE_FLAGS="--enable-shared=no --prefix=$PREFIX"
COMMON_MAKE_INSTALL_FLAGS="-j$CPUS BUILD_SHARED=no PREFIX=$PREFIX install" 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 [ ! -f $PREFIX/include/bzlib.h ]; then
if [ -d bzip2-$BZIP2_VERSION ]; then if [ -d bzip2-$BZIP2_VERSION ]; then
rm -rf bzip2-$BZIP2_VERSION rm -rf bzip2-$BZIP2_VERSION
@ -845,7 +876,7 @@ if [ ! -f $PREFIX/include/bzlib.h ]; then
popd popd
fi fi
# install fmt log_tool_name "fmt $FMT_VERSION"
if [ ! -d $PREFIX/include/fmt ]; then if [ ! -d $PREFIX/include/fmt ]; then
if [ -d fmt-$FMT_VERSION ]; then if [ -d fmt-$FMT_VERSION ]; then
rm -rf fmt-$FMT_VERSION rm -rf fmt-$FMT_VERSION
@ -858,7 +889,7 @@ if [ ! -d $PREFIX/include/fmt ]; then
popd && popd popd && popd
fi fi
# install lz4 log_tool_name "lz4 $LZ4_VERSION"
if [ ! -f $PREFIX/include/lz4.h ]; then if [ ! -f $PREFIX/include/lz4.h ]; then
if [ -d lz4-$LZ4_VERSION ]; then if [ -d lz4-$LZ4_VERSION ]; then
rm -rf lz4-$LZ4_VERSION rm -rf lz4-$LZ4_VERSION
@ -869,7 +900,7 @@ if [ ! -f $PREFIX/include/lz4.h ]; then
popd popd
fi fi
# install xz log_tool_name "xz $XZ_VERSION"
if [ ! -f $PREFIX/include/lzma.h ]; then if [ ! -f $PREFIX/include/lzma.h ]; then
if [ -d xz-$XZ_VERSION ]; then if [ -d xz-$XZ_VERSION ]; then
rm -rf xz-$XZ_VERSION rm -rf xz-$XZ_VERSION
@ -881,7 +912,7 @@ if [ ! -f $PREFIX/include/lzma.h ]; then
popd popd
fi fi
# install zlib log_tool_name "zlib $ZLIB_VERSION"
if [ ! -f $PREFIX/include/zlib.h ]; then if [ ! -f $PREFIX/include/zlib.h ]; then
if [ -d zlib-$ZLIB_VERSION ]; then if [ -d zlib-$ZLIB_VERSION ]; then
rm -rf zlib-$ZLIB_VERSION rm -rf zlib-$ZLIB_VERSION
@ -895,7 +926,7 @@ if [ ! -f $PREFIX/include/zlib.h ]; then
popd && popd popd && popd
fi fi
# install zstd log_tool_name "zstd $ZSTD_VERSION"
if [ ! -f $PREFIX/include/zstd.h ]; then if [ ! -f $PREFIX/include/zstd.h ]; then
if [ -d zstd-$ZSTD_VERSION ]; then if [ -d zstd-$ZSTD_VERSION ]; then
rm -rf zstd-$ZSTD_VERSION rm -rf zstd-$ZSTD_VERSION
@ -910,7 +941,8 @@ if [ ! -f $PREFIX/include/zstd.h ]; then
popd && popd popd && popd
fi fi
#install jemalloc # TODO(gitbuda): Freeze jmalloc version.
log_tool_name "jmalloc"
if [ ! -d $PREFIX/include/jemalloc ]; then if [ ! -d $PREFIX/include/jemalloc ]; then
if [ -d jemalloc ]; then if [ -d jemalloc ]; then
rm -rf jemalloc rm -rf jemalloc
@ -927,7 +959,7 @@ if [ ! -d $PREFIX/include/jemalloc ]; then
popd popd
fi fi
# install boost log_tool_name "BOOST $BOOST_VERSION"
if [ ! -d $PREFIX/include/boost ]; then if [ ! -d $PREFIX/include/boost ]; then
if [ -d boost_$BOOST_VERSION_UNDERSCORES ]; then if [ -d boost_$BOOST_VERSION_UNDERSCORES ]; then
rm -rf boost_$BOOST_VERSION_UNDERSCORES 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 tar -xzf ../archives/boost_$BOOST_VERSION_UNDERSCORES.tar.gz
pushd boost_$BOOST_VERSION_UNDERSCORES pushd boost_$BOOST_VERSION_UNDERSCORES
./bootstrap.sh --prefix=$PREFIX --with-toolset=clang --with-python=python3 --without-icu ./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 \ if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
-sZLIB_SOURCE="$PREFIX" -sZLIB_INCLUDE="$PREFIX/include" -sZLIB_LIBPATH="$PREFIX/lib" \ ./b2 toolset=clang -j$CPUS install variant=release link=static cxxstd=20 --disable-icu \
-sBZIP2_SOURCE="$PREFIX" -sBZIP2_INCLUDE="$PREFIX/include" -sBZIP2_LIBPATH="$PREFIX/lib" \ -sZLIB_SOURCE="$PREFIX" -sZLIB_INCLUDE="$PREFIX/include" -sZLIB_LIBPATH="$PREFIX/lib" \
-sLZMA_SOURCE="$PREFIX" -sLZMA_INCLUDE="$PREFIX/include" -sLZMA_LIBPATH="$PREFIX/lib" \ -sBZIP2_SOURCE="$PREFIX" -sBZIP2_INCLUDE="$PREFIX/include" -sBZIP2_LIBPATH="$PREFIX/lib" \
-sZSTD_SOURCE="$PREFIX" -sZSTD_INCLUDE="$PREFIX/include" -sZSTD_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 popd
fi fi
# install double-conversion log_tool_name "double-conversion $DOUBLE_CONVERSION_VERSION"
if [ ! -d $PREFIX/include/double-conversion ]; then if [ ! -d $PREFIX/include/double-conversion ]; then
if [ -d double-conversion-$DOUBLE_CONVERSION_VERSION ]; then if [ -d double-conversion-$DOUBLE_CONVERSION_VERSION ]; then
rm -rf double-conversion-$DOUBLE_CONVERSION_VERSION rm -rf double-conversion-$DOUBLE_CONVERSION_VERSION
@ -958,7 +999,8 @@ if [ ! -d $PREFIX/include/double-conversion ]; then
popd && popd popd && popd
fi fi
# install gflags # TODO(gitbuda): Freeze gflags version.
log_tool_name "gflags"
if [ ! -d $PREFIX/include/gflags ]; then if [ ! -d $PREFIX/include/gflags ]; then
if [ -d gflags ]; then if [ -d gflags ]; then
rm -rf gflags rm -rf gflags
@ -977,7 +1019,7 @@ if [ ! -d $PREFIX/include/gflags ]; then
popd && popd popd && popd
fi fi
# install libunwind log_tool_name "libunwind $LIBUNWIND_VERSION"
if [ ! -f $PREFIX/include/libunwind.h ]; then if [ ! -f $PREFIX/include/libunwind.h ]; then
if [ -d libunwind-$LIBUNWIND_VERSION ]; then if [ -d libunwind-$LIBUNWIND_VERSION ]; then
rm -rf libunwind-$LIBUNWIND_VERSION rm -rf libunwind-$LIBUNWIND_VERSION
@ -990,7 +1032,7 @@ if [ ! -f $PREFIX/include/libunwind.h ]; then
popd popd
fi fi
# install glog log_tool_name "glog $GLOG_VERSION"
if [ ! -d $PREFIX/include/glog ]; then if [ ! -d $PREFIX/include/glog ]; then
if [ -d glog-$GLOG_VERSION ]; then if [ -d glog-$GLOG_VERSION ]; then
rm -rf glog-$GLOG_VERSION rm -rf glog-$GLOG_VERSION
@ -1004,7 +1046,7 @@ if [ ! -d $PREFIX/include/glog ]; then
popd && popd popd && popd
fi fi
# install libevent log_tool_name "libevent $LIBEVENT_VERSION"
if [ ! -d $PREFIX/include/event2 ]; then if [ ! -d $PREFIX/include/event2 ]; then
if [ -d libevent-$LIBEVENT_VERSION ]; then if [ -d libevent-$LIBEVENT_VERSION ]; then
rm -rf libevent-$LIBEVENT_VERSION rm -rf libevent-$LIBEVENT_VERSION
@ -1023,7 +1065,7 @@ if [ ! -d $PREFIX/include/event2 ]; then
popd && popd popd && popd
fi fi
# install snappy log_tool_name "snappy $SNAPPY_VERSION"
if [ ! -f $PREFIX/include/snappy.h ]; then if [ ! -f $PREFIX/include/snappy.h ]; then
if [ -d snappy-$SNAPPY_VERSION ]; then if [ -d snappy-$SNAPPY_VERSION ]; then
rm -rf snappy-$SNAPPY_VERSION rm -rf snappy-$SNAPPY_VERSION
@ -1041,7 +1083,7 @@ if [ ! -f $PREFIX/include/snappy.h ]; then
popd && popd popd && popd
fi fi
# install libsodium log_tool_name "libsodium $LIBSODIUM_VERSION"
if [ ! -f $PREFIX/include/sodium.h ]; then if [ ! -f $PREFIX/include/sodium.h ]; then
if [ -d libsodium-$LIBSODIUM_VERSION ]; then if [ -d libsodium-$LIBSODIUM_VERSION ]; then
rm -rf libsodium-$LIBSODIUM_VERSION rm -rf libsodium-$LIBSODIUM_VERSION
@ -1053,7 +1095,7 @@ if [ ! -f $PREFIX/include/sodium.h ]; then
popd popd
fi fi
# install libaio log_tool_name "libaio $LIBAIO_VERSION"
if [ ! -f $PREFIX/include/libaio.h ]; then if [ ! -f $PREFIX/include/libaio.h ]; then
if [ -d libaio-$LIBAIO_VERSION ]; then if [ -d libaio-$LIBAIO_VERSION ]; then
rm -rf libaio-$LIBAIO_VERSION rm -rf libaio-$LIBAIO_VERSION
@ -1064,7 +1106,7 @@ if [ ! -f $PREFIX/include/libaio.h ]; then
popd popd
fi fi
# install folly log_tool_name "folly $FBLIBS_VERSION"
if [ ! -d $PREFIX/include/folly ]; then if [ ! -d $PREFIX/include/folly ]; then
if [ -d folly-$FBLIBS_VERSION ]; then if [ -d folly-$FBLIBS_VERSION ]; then
rm -rf folly-$FBLIBS_VERSION rm -rf folly-$FBLIBS_VERSION
@ -1085,7 +1127,7 @@ if [ ! -d $PREFIX/include/folly ]; then
popd && popd popd && popd
fi fi
# install fizz log_tool_name "fizz $FBLIBS_VERSION"
if [ ! -d $PREFIX/include/fizz ]; then if [ ! -d $PREFIX/include/fizz ]; then
if [ -d fizz-$FBLIBS_VERSION ]; then if [ -d fizz-$FBLIBS_VERSION ]; then
rm -rf fizz-$FBLIBS_VERSION rm -rf fizz-$FBLIBS_VERSION
@ -1104,7 +1146,7 @@ if [ ! -d $PREFIX/include/fizz ]; then
popd && popd popd && popd
fi fi
# install wangle log_tool_name "wangle FBLIBS_VERSION"
if [ ! -d $PREFIX/include/wangle ]; then if [ ! -d $PREFIX/include/wangle ]; then
if [ -d wangle-$FBLIBS_VERSION ]; then if [ -d wangle-$FBLIBS_VERSION ]; then
rm -rf wangle-$FBLIBS_VERSION rm -rf wangle-$FBLIBS_VERSION
@ -1123,7 +1165,7 @@ if [ ! -d $PREFIX/include/wangle ]; then
popd && popd popd && popd
fi fi
# install proxygen log_tool_name "proxygen $FBLIBS_VERSION"
if [ ! -d $PREFIX/include/proxygen ]; then if [ ! -d $PREFIX/include/proxygen ]; then
if [ -d proxygen-$FBLIBS_VERSION ]; then if [ -d proxygen-$FBLIBS_VERSION ]; then
rm -rf proxygen-$FBLIBS_VERSION rm -rf proxygen-$FBLIBS_VERSION
@ -1144,7 +1186,7 @@ if [ ! -d $PREFIX/include/proxygen ]; then
popd && popd popd && popd
fi fi
# install flex log_tool_name "flex $FBLIBS_VERSION"
if [ ! -f $PREFIX/include/FlexLexer.h ]; then if [ ! -f $PREFIX/include/FlexLexer.h ]; then
if [ -d flex-$FLEX_VERSION ]; then if [ -d flex-$FLEX_VERSION ]; then
rm -rf flex-$FLEX_VERSION rm -rf flex-$FLEX_VERSION
@ -1156,7 +1198,7 @@ if [ ! -f $PREFIX/include/FlexLexer.h ]; then
popd popd
fi fi
# install fbthrift log_tool_name "fbthrift $FBLIBS_VERSION"
if [ ! -d $PREFIX/include/thrift ]; then if [ ! -d $PREFIX/include/thrift ]; then
if [ -d fbthrift-$FBLIBS_VERSION ]; then if [ -d fbthrift-$FBLIBS_VERSION ]; then
rm -rf fbthrift-$FBLIBS_VERSION rm -rf fbthrift-$FBLIBS_VERSION
@ -1166,10 +1208,15 @@ if [ ! -d $PREFIX/include/thrift ]; then
# build is used by facebook builder # build is used by facebook builder
mkdir _build mkdir _build
pushd _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 \ cmake .. $COMMON_CMAKE_FLAGS \
-Denable_tests=OFF \ -Denable_tests=OFF \
-DGFLAGS_NOTHREADS=OFF \ -DGFLAGS_NOTHREADS=OFF \
-DCMAKE_CXX_FLAGS=-fsized-deallocation -DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS"
make -j$CPUS install make -j$CPUS install
popd popd
fi fi
@ -1192,7 +1239,12 @@ if [ ! -f $NAME-binaries-$DISTRO.tar.gz ]; then
DISTRO_FULL_NAME="$DISTRO_FULL_NAME-amd64" DISTRO_FULL_NAME="$DISTRO_FULL_NAME-amd64"
fi fi
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 tar --owner=root --group=root -cpvzf $NAME-binaries-$DISTRO_FULL_NAME.tar.gz -C /opt $NAME
fi fi

View File

@ -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 3. using the Licensed Work to create a work or solution
which competes (or might reasonably be expected to which competes (or might reasonably be expected to
compete) with the Licensed Work. compete) with the Licensed Work.
CHANGE DATE: 2026-07-10 CHANGE DATE: 2026-07-11
CHANGE LICENSE: Apache License, Version 2.0 CHANGE LICENSE: Apache License, Version 2.0
For information about alternative licensing arrangements, please visit: https://memgraph.com/legal. For information about alternative licensing arrangements, please visit: https://memgraph.com/legal.

View File

@ -2,8 +2,8 @@ MEMGRAPH
ENTERPRISE LICENCE AGREEMENT ENTERPRISE LICENCE AGREEMENT
Memgraph Limited is registered in England under registration 10195084 and has its registered office at Suite 4, Memgraph Limited is registered in England under registration 10195084 and has its registered office at 90a High Street,
Ironstone House, Ironstone Way, Brixworth, Northampton, NN6 9UD (“Memgraph”). 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 Memgraph agrees to license and/or grant you (the “Customer”) access to the Software ( as defined below) and provide

View File

@ -1,4 +1,11 @@
# mgp # mgp
PyPi package used for type hinting when creating MAGE modules. The get started PyPi package used for type hinting when creating query modules. Repository of already available query modules is called [MAGE](https://github.com/memgraph/mage).
using MAGE repository checkout the repository here: 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

View File

@ -257,3 +257,11 @@ class _MODULE:
@staticmethod @staticmethod
def add_function(wrapper): def add_function(wrapper):
pass pass
class SOURCE_TYPE_KAFKA:
pass
class SOURCE_TYPE_PULSAR:
pass

View File

@ -1,13 +1,13 @@
[tool.poetry] [tool.poetry]
name = "mgp" name = "mgp"
version = "1.0.0" version = "1.1.0"
description = "Memgraph's module for developing MAGE modules. Used only for type hinting!" description = "Memgraph's module for developing MAGE modules. Used only for type hinting!"
authors = [ authors = [
"MasterMedo <mislav.vuletic@gmail.com>",
"jbajic <jure.bajic@memgraph.io>",
"katarinasupe <katarina.supe@memgraph.io>", "katarinasupe <katarina.supe@memgraph.io>",
"jbajic <jure.bajic@memgraph.io>",
"antejavor <ante.javor@memgraph.io>", "antejavor <ante.javor@memgraph.io>",
"antaljanosbenjamin <benjamin.antal@memgraph.io>", "antaljanosbenjamin <benjamin.antal@memgraph.io>",
"MasterMedo <mislav.vuletic@gmail.com>",
] ]
license = "Apache-2.0" license = "Apache-2.0"
readme = "README.md" readme = "README.md"

View File

@ -15,10 +15,11 @@ add_subdirectory(query)
add_subdirectory(glue) add_subdirectory(glue)
add_subdirectory(slk) add_subdirectory(slk)
add_subdirectory(rpc) add_subdirectory(rpc)
add_subdirectory(license)
add_subdirectory(auth) add_subdirectory(auth)
if (MG_ENTERPRISE) if(MG_ENTERPRISE)
add_subdirectory(audit) add_subdirectory(audit)
endif() endif()
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type) 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 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) 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 if(MG_ENTERPRISE)
set(mg_single_node_v2_libs ${mg_single_node_v2_libs} mg-audit) # These are enterprise subsystems
set(mg_single_node_v2_libs ${mg_single_node_v2_libs} mg-audit)
endif() endif()
# memgraph main executable # memgraph main executable
add_executable(memgraph ${mg_single_node_v2_sources}) add_executable(memgraph ${mg_single_node_v2_sources})
target_include_directories(memgraph PUBLIC ${CMAKE_SOURCE_DIR}/include) target_include_directories(memgraph PUBLIC ${CMAKE_SOURCE_DIR}/include)
target_link_libraries(memgraph ${mg_single_node_v2_libs}) target_link_libraries(memgraph ${mg_single_node_v2_libs})
# NOTE: `include/mg_procedure.syms` describes a pattern match for symbols which # NOTE: `include/mg_procedure.syms` describes a pattern match for symbols which
# should be dynamically exported, so that `dlopen` can correctly link the # should be dynamically exported, so that `dlopen` can correctly link the
# symbols in custom procedure module libraries. # symbols in custom procedure module libraries.
target_link_libraries(memgraph "-Wl,--dynamic-list=${CMAKE_SOURCE_DIR}/include/mg_procedure.syms") target_link_libraries(memgraph "-Wl,--dynamic-list=${CMAKE_SOURCE_DIR}/include/mg_procedure.syms")
set_target_properties(memgraph PROPERTIES set_target_properties(memgraph PROPERTIES
# Set the executable output name to include version information.
OUTPUT_NAME "memgraph-${MEMGRAPH_VERSION}_${CMAKE_BUILD_TYPE}" # Set the executable output name to include version information.
# Output the executable in main binary dir. OUTPUT_NAME "memgraph-${MEMGRAPH_VERSION}_${CMAKE_BUILD_TYPE}"
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
# Output the executable in main binary dir.
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
# Create symlink to the built executable. # Create symlink to the built executable.
add_custom_command(TARGET memgraph POST_BUILD add_custom_command(TARGET memgraph POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:memgraph> ${CMAKE_BINARY_DIR}/memgraph COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:memgraph> ${CMAKE_BINARY_DIR}/memgraph
BYPRODUCTS ${CMAKE_BINARY_DIR}/memgraph BYPRODUCTS ${CMAKE_BINARY_DIR}/memgraph
COMMENT "Creating symlink to memgraph executable") COMMENT "Creating symlink to memgraph executable")
# Emulate the installed python_support, by creating a symlink # Emulate the installed python_support, by creating a symlink
add_custom_command(TARGET memgraph POST_BUILD add_custom_command(TARGET memgraph POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/python_support COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/python_support
BYPRODUCTS ${CMAKE_BINARY_DIR}/python_support BYPRODUCTS ${CMAKE_BINARY_DIR}/python_support
COMMENT "Creating symlink for python_support") COMMENT "Creating symlink for python_support")
# Strip the executable in release build. # Strip the executable in release build.
if (lower_build_type STREQUAL "release") if(lower_build_type STREQUAL "release")
add_custom_command(TARGET memgraph POST_BUILD add_custom_command(TARGET memgraph POST_BUILD
COMMAND strip -s $<TARGET_FILE:memgraph> COMMAND strip -s $<TARGET_FILE:memgraph>
COMMENT "Stripping symbols and sections from memgraph") COMMENT "Stripping symbols and sections from memgraph")
endif() endif()
# Generate the configuration file. # Generate the configuration file.
add_custom_command(TARGET memgraph POST_BUILD add_custom_command(TARGET memgraph POST_BUILD
COMMAND ${CMAKE_SOURCE_DIR}/config/generate.py COMMAND ${CMAKE_SOURCE_DIR}/config/generate.py
${CMAKE_BINARY_DIR}/memgraph ${CMAKE_BINARY_DIR}/memgraph
${CMAKE_BINARY_DIR}/config/memgraph.conf ${CMAKE_BINARY_DIR}/config/memgraph.conf
DEPENDS ${CMAKE_SOURCE_DIR}/config/generate.py DEPENDS ${CMAKE_SOURCE_DIR}/config/generate.py
${CMAKE_SOURCE_DIR}/config/flags.yaml ${CMAKE_SOURCE_DIR}/config/flags.yaml
BYPRODUCTS ${CMAKE_BINARY_DIR}/config/memgraph.conf BYPRODUCTS ${CMAKE_BINARY_DIR}/config/memgraph.conf
COMMENT "Generating memgraph configuration file") COMMENT "Generating memgraph configuration file")
# Everything here is under "memgraph" install component. # Everything here is under "memgraph" install component.
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "memgraph") set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "memgraph")
# TODO: Default directory permissions to 755 # TODO: Default directory permissions to 755
# NOTE: This is added in CMake 3.11, so enable it then # NOTE: This is added in CMake 3.11, so enable it then
#set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS # set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
# OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ WORLD_READ) # OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ WORLD_READ)
# Install and rename executable to just 'memgraph' Since we have to rename, # Install and rename executable to just 'memgraph' Since we have to rename,
# we cannot use the recommended `install(TARGETS ...)`. # we cannot use the recommended `install(TARGETS ...)`.
install(PROGRAMS $<TARGET_FILE:memgraph> install(PROGRAMS $<TARGET_FILE:memgraph>
DESTINATION lib/memgraph RENAME memgraph) DESTINATION lib/memgraph RENAME memgraph)
# Install Python source for supporting our embedded Python. # Install Python source for supporting our embedded Python.
install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.py install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.py
DESTINATION lib/memgraph/python_support) DESTINATION lib/memgraph/python_support)
# Install the includes file for writing custom procedures in C and C++> # Install the includes file for writing custom procedures in C and C++>
install(FILES ${CMAKE_SOURCE_DIR}/include/mg_procedure.h install(FILES ${CMAKE_SOURCE_DIR}/include/mg_procedure.h
DESTINATION include/memgraph) DESTINATION include/memgraph)
@ -107,9 +116,11 @@ install(FILES ${CMAKE_SOURCE_DIR}/include/mg_exceptions.hpp
DESTINATION include/memgraph) DESTINATION include/memgraph)
install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.hpp install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.hpp
DESTINATION include/memgraph) DESTINATION include/memgraph)
# Install the config file (must use absolute path). # Install the config file (must use absolute path).
install(FILES ${CMAKE_BINARY_DIR}/config/memgraph.conf install(FILES ${CMAKE_BINARY_DIR}/config/memgraph.conf
DESTINATION /etc/memgraph RENAME memgraph.conf) DESTINATION /etc/memgraph RENAME memgraph.conf)
# Install logrotate configuration (must use absolute path). # Install logrotate configuration (must use absolute path).
install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate.conf install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate.conf
DESTINATION /etc/logrotate.d RENAME memgraph) 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 # Memgraph CSV Import Tool Executable
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
add_executable(mg_import_csv mg_import_csv.cpp) add_executable(mg_import_csv mg_import_csv.cpp)
target_link_libraries(mg_import_csv mg-storage-v2) target_link_libraries(mg_import_csv mg-storage-v2)
# Strip the executable in release build. # Strip the executable in release build.
if (lower_build_type STREQUAL "release") if(lower_build_type STREQUAL "release")
add_custom_command(TARGET mg_import_csv POST_BUILD add_custom_command(TARGET mg_import_csv POST_BUILD
COMMAND strip -s mg_import_csv COMMAND strip -s mg_import_csv
COMMENT "Stripping symbols and sections from mg_import_csv") COMMENT "Stripping symbols and sections from mg_import_csv")
endif() endif()
install(TARGETS mg_import_csv RUNTIME DESTINATION bin) install(TARGETS mg_import_csv RUNTIME DESTINATION bin)

View File

@ -16,8 +16,8 @@
#include <fmt/format.h> #include <fmt/format.h>
#include "auth/exceptions.hpp" #include "auth/exceptions.hpp"
#include "license/license.hpp"
#include "utils/flag_validation.hpp" #include "utils/flag_validation.hpp"
#include "utils/license.hpp"
#include "utils/logging.hpp" #include "utils/logging.hpp"
#include "utils/message.hpp" #include "utils/message.hpp"
#include "utils/settings.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) { std::optional<User> Auth::Authenticate(const std::string &username, const std::string &password) {
if (module_.IsUsed()) { 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()) { if (license_check_result.HasError()) {
spdlog::warn( spdlog::warn(license::LicenseCheckErrorToString(license_check_result.GetError(), "authentication modules"));
utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "authentication modules"));
return std::nullopt; return std::nullopt;
} }

View File

@ -15,8 +15,8 @@
#include "auth/crypto.hpp" #include "auth/crypto.hpp"
#include "auth/exceptions.hpp" #include "auth/exceptions.hpp"
#include "license/license.hpp"
#include "utils/cast.hpp" #include "utils/cast.hpp"
#include "utils/license.hpp"
#include "utils/logging.hpp" #include "utils/logging.hpp"
#include "utils/settings.hpp" #include "utils/settings.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
@ -242,7 +242,7 @@ FineGrainedAccessPermissions::FineGrainedAccessPermissions(const std::unordered_
PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission, PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission,
const FineGrainedPermission fine_grained_permission) const { const FineGrainedPermission fine_grained_permission) const {
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return PermissionLevel::GRANT; return PermissionLevel::GRANT;
} }
const auto concrete_permission = std::invoke([&]() -> uint64_t { const auto concrete_permission = std::invoke([&]() -> uint64_t {
@ -281,7 +281,7 @@ void FineGrainedAccessPermissions::Revoke(const std::string &permission) {
} }
nlohmann::json FineGrainedAccessPermissions::Serialize() const { nlohmann::json FineGrainedAccessPermissions::Serialize() const {
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return {}; return {};
} }
nlohmann::json data = nlohmann::json::object(); nlohmann::json data = nlohmann::json::object();
@ -294,7 +294,7 @@ FineGrainedAccessPermissions FineGrainedAccessPermissions::Deserialize(const nlo
if (!data.is_object()) { if (!data.is_object()) {
throw AuthException("Couldn't load permissions data!"); throw AuthException("Couldn't load permissions data!");
} }
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return FineGrainedAccessPermissions{}; return FineGrainedAccessPermissions{};
} }
std::optional<uint64_t> global_permission; 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_; } FineGrainedAccessPermissions &FineGrainedAccessHandler::edge_type_permissions() { return edge_type_permissions_; }
nlohmann::json FineGrainedAccessHandler::Serialize() const { nlohmann::json FineGrainedAccessHandler::Serialize() const {
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return {}; return {};
} }
nlohmann::json data = nlohmann::json::object(); 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()) { if (!data["label_permissions"].is_object() || !data["edge_type_permissions"].is_object()) {
throw AuthException("Couldn't load label_permissions or edge_type_permissions data!"); 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{}; return FineGrainedAccessHandler{};
} }
auto label_permissions = FineGrainedAccessPermissions::Deserialize(data["label_permissions"]); auto label_permissions = FineGrainedAccessPermissions::Deserialize(data["label_permissions"]);
@ -414,7 +414,7 @@ nlohmann::json Role::Serialize() const {
data["rolename"] = rolename_; data["rolename"] = rolename_;
data["permissions"] = permissions_.Serialize(); data["permissions"] = permissions_.Serialize();
#ifdef MG_ENTERPRISE #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(); data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize();
} else { } else {
data["fine_grained_access_handler"] = {}; data["fine_grained_access_handler"] = {};
@ -432,7 +432,7 @@ Role Role::Deserialize(const nlohmann::json &data) {
} }
auto permissions = Permissions::Deserialize(data["permissions"]); auto permissions = Permissions::Deserialize(data["permissions"]);
#ifdef MG_ENTERPRISE #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()) { if (!data["fine_grained_access_handler"].is_object()) {
throw AuthException("Couldn't load user data!"); 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) { bool operator==(const Role &first, const Role &second) {
#ifdef MG_ENTERPRISE #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_ && return first.rolename_ == second.rolename_ && first.permissions_ == second.permissions_ &&
first.fine_grained_access_handler_ == second.fine_grained_access_handler_; 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 (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()) { license_check_result.HasError()) {
throw AuthException( throw AuthException(
"Custom password regex is a Memgraph Enterprise feature. Please set the config " "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{}", "(\"--auth-password-strength-regex\") to its default value (\"{}\") or remove the flag.\n{}",
default_password_regex, 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); std::regex re(FLAGS_auth_password_strength_regex);
@ -517,7 +517,7 @@ Permissions User::GetPermissions() const {
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const { FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const {
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return FineGrainedAccessPermissions{}; return FineGrainedAccessPermissions{};
} }
@ -530,7 +530,7 @@ FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const
} }
FineGrainedAccessPermissions User::GetFineGrainedAccessEdgeTypePermissions() const { FineGrainedAccessPermissions User::GetFineGrainedAccessEdgeTypePermissions() const {
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return FineGrainedAccessPermissions{}; return FineGrainedAccessPermissions{};
} }
if (role_) { if (role_) {
@ -563,7 +563,7 @@ nlohmann::json User::Serialize() const {
data["password_hash"] = password_hash_; data["password_hash"] = password_hash_;
data["permissions"] = permissions_.Serialize(); data["permissions"] = permissions_.Serialize();
#ifdef MG_ENTERPRISE #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(); data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize();
} else { } else {
data["fine_grained_access_handler"] = {}; data["fine_grained_access_handler"] = {};
@ -582,7 +582,7 @@ User User::Deserialize(const nlohmann::json &data) {
} }
auto permissions = Permissions::Deserialize(data["permissions"]); auto permissions = Permissions::Deserialize(data["permissions"]);
#ifdef MG_ENTERPRISE #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()) { if (!data["fine_grained_access_handler"].is_object()) {
throw AuthException("Couldn't load user data!"); 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) { bool operator==(const User &first, const User &second) {
#ifdef MG_ENTERPRISE #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_ && return first.username_ == second.username_ && first.password_hash_ == second.password_hash_ &&
first.permissions_ == second.permissions_ && first.role_ == second.role_ && first.permissions_ == second.permissions_ && first.role_ == second.role_ &&
first.fine_grained_access_handler_ == second.fine_grained_access_handler_; first.fine_grained_access_handler_ == second.fine_grained_access_handler_;

View File

@ -14,8 +14,8 @@
#include "auth/auth.hpp" #include "auth/auth.hpp"
#include "auth/models.hpp" #include "auth/models.hpp"
#include "glue/auth.hpp" #include "glue/auth.hpp"
#include "license/license.hpp"
#include "query/frontend/ast/ast.hpp" #include "query/frontend/ast/ast.hpp"
#include "utils/license.hpp"
#include "utils/synchronized.hpp" #include "utils/synchronized.hpp"
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
@ -23,7 +23,7 @@ namespace {
bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba, bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba,
const std::vector<memgraph::storage::LabelId> &labels, const std::vector<memgraph::storage::LabelId> &labels,
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) { 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 true;
} }
return std::all_of(labels.begin(), labels.end(), [dba, &user, fine_grained_privilege](const auto &label) { 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, bool IsUserAuthorizedGloballyLabels(const memgraph::auth::User &user,
const memgraph::auth::FineGrainedPermission fine_grained_permission) { 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 true;
} }
return user.GetFineGrainedAccessLabelPermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) == 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, bool IsUserAuthorizedGloballyEdges(const memgraph::auth::User &user,
const memgraph::auth::FineGrainedPermission fine_grained_permission) { 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 true;
} }
return user.GetFineGrainedAccessEdgeTypePermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) == 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, bool IsUserAuthorizedEdgeType(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba,
const memgraph::storage::EdgeTypeId &edgeType, const memgraph::storage::EdgeTypeId &edgeType,
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) { 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 true;
} }
return user.GetFineGrainedAccessEdgeTypePermissions().Has( return user.GetFineGrainedAccessEdgeTypePermissions().Has(
@ -87,7 +87,7 @@ bool AuthChecker::IsUserAuthorized(const std::optional<std::string> &username,
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
std::unique_ptr<memgraph::query::FineGrainedAuthChecker> AuthChecker::GetFineGrainedAuthChecker( std::unique_ptr<memgraph::query::FineGrainedAuthChecker> AuthChecker::GetFineGrainedAuthChecker(
const std::string &username, const memgraph::query::DbAccessor *dba) const { 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 {}; return {};
} }
try { try {
@ -154,7 +154,7 @@ bool FineGrainedAuthChecker::Has(const memgraph::storage::EdgeTypeId &edge_type,
bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices( bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices(
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const { 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 true;
} }
return IsUserAuthorizedGloballyLabels(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege)); return IsUserAuthorizedGloballyLabels(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege));
@ -162,7 +162,7 @@ bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices(
bool FineGrainedAuthChecker::HasGlobalPrivilegeOnEdges( bool FineGrainedAuthChecker::HasGlobalPrivilegeOnEdges(
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const { 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 true;
} }
return IsUserAuthorizedGloballyEdges(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege)); return IsUserAuthorizedGloballyEdges(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege));

View File

@ -17,7 +17,7 @@
#include "auth/models.hpp" #include "auth/models.hpp"
#include "glue/auth.hpp" #include "glue/auth.hpp"
#include "utils/license.hpp" #include "license/license.hpp"
namespace { namespace {
@ -125,7 +125,7 @@ std::vector<FineGrainedPermissionForPrivilegeResult> GetFineGrainedPermissionFor
const memgraph::auth::FineGrainedAccessPermissions &permissions, const std::string &permission_type, const memgraph::auth::FineGrainedAccessPermissions &permissions, const std::string &permission_type,
const std::string &user_or_role) { const std::string &user_or_role) {
std::vector<FineGrainedPermissionForPrivilegeResult> fine_grained_permissions; 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; return fine_grained_permissions;
} }
const auto global_permission = permissions.GetGlobalPermission(); const auto global_permission = permissions.GetGlobalPermission();
@ -166,7 +166,7 @@ std::vector<FineGrainedPermissionForPrivilegeResult> GetFineGrainedPermissionFor
std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivilegesResult( std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivilegesResult(
const std::vector<FineGrainedPermissionForPrivilegeResult> &privileges) { const std::vector<FineGrainedPermissionForPrivilegeResult> &privileges) {
std::vector<std::vector<memgraph::query::TypedValue>> grants; std::vector<std::vector<memgraph::query::TypedValue>> grants;
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return {}; return {};
} }
grants.reserve(privileges.size()); grants.reserve(privileges.size());
@ -182,7 +182,7 @@ std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivil
std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivileges( std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivileges(
const std::optional<memgraph::auth::User> &user) { const std::optional<memgraph::auth::User> &user) {
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return {}; return {};
} }
const auto &label_permissions = user->GetFineGrainedAccessLabelPermissions(); 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( std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedRolePrivileges(
const std::optional<memgraph::auth::Role> &role) { const std::optional<memgraph::auth::Role> &role) {
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
return {}; return {};
} }
const auto &label_permissions = role->GetFineGrainedAccessLabelPermissions(); 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) { bool AuthQueryHandler::CreateUser(const std::string &username, const std::optional<std::string> &password) {
if (name_regex_string_ != kDefaultUserRoleRegex) { if (name_regex_string_ != kDefaultUserRoleRegex) {
if (const auto license_check_result = 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()) { license_check_result.HasError()) {
throw memgraph::auth::AuthException( throw memgraph::auth::AuthException(
"Custom user/role regex is a Memgraph Enterprise feature. Please set the config " "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{}", "(\"--auth-user-or-role-name-regex\") to its default value (\"{}\") or remove the flag.\n{}",
kDefaultUserRoleRegex, 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_)) { if (!std::regex_match(username, name_regex_)) {
@ -473,20 +473,20 @@ std::vector<std::vector<memgraph::query::TypedValue>> AuthQueryHandler::GetPrivi
if (user) { if (user) {
grants = ShowUserPrivileges(user); grants = ShowUserPrivileges(user);
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
fine_grained_grants = ShowFineGrainedUserPrivileges(user); fine_grained_grants = ShowFineGrainedUserPrivileges(user);
} }
#endif #endif
} else { } else {
grants = ShowRolePrivileges(role); grants = ShowRolePrivileges(role);
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
fine_grained_grants = ShowFineGrainedRolePrivileges(role); fine_grained_grants = ShowFineGrainedRolePrivileges(role);
} }
#endif #endif
} }
#ifdef MG_ENTERPRISE #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()); grants.insert(grants.end(), fine_grained_grants.begin(), fine_grained_grants.end());
} }
#endif #endif
@ -627,7 +627,7 @@ void AuthQueryHandler::EditPermissions(
edit_permissions_fun(user->permissions(), permission); edit_permissions_fun(user->permissions(), permission);
} }
#ifdef MG_ENTERPRISE #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) { for (const auto &label_privilege_collection : label_privileges) {
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(),
label_privilege_collection); label_privilege_collection);
@ -644,7 +644,7 @@ void AuthQueryHandler::EditPermissions(
edit_permissions_fun(role->permissions(), permission); edit_permissions_fun(role->permissions(), permission);
} }
#ifdef MG_ENTERPRISE #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) { for (const auto &label_privilege : label_privileges) {
edit_fine_grained_permissions_fun(role->fine_grained_access_handler().label_permissions(), label_privilege); edit_fine_grained_permissions_fun(role->fine_grained_access_handler().label_permissions(), label_privilege);
} }

View File

@ -15,8 +15,8 @@
#include "auth/auth.hpp" #include "auth/auth.hpp"
#include "glue/auth.hpp" #include "glue/auth.hpp"
#include "license/license.hpp"
#include "query/interpreter.hpp" #include "query/interpreter.hpp"
#include "utils/license.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
namespace memgraph::glue { namespace memgraph::glue {

View 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)

View File

@ -9,17 +9,19 @@
// by the Apache License, Version 2.0, included in the file // by the Apache License, Version 2.0, included in the file
// licenses/APL.txt. // licenses/APL.txt.
#include "utils/license.hpp" #include "license/license.hpp"
#include <atomic> #include <atomic>
#include <charconv> #include <charconv>
#include <chrono> #include <chrono>
#include <cstdint>
#include <functional> #include <functional>
#include <optional> #include <optional>
#include <unordered_map> #include <unordered_map>
#include "slk/serialization.hpp" #include "slk/serialization.hpp"
#include "utils/base64.hpp" #include "utils/base64.hpp"
#include "utils/cast.hpp"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
#include "utils/logging.hpp" #include "utils/logging.hpp"
#include "utils/memory_tracker.hpp" #include "utils/memory_tracker.hpp"
@ -27,7 +29,7 @@
#include "utils/spin_lock.hpp" #include "utils/spin_lock.hpp"
#include "utils/synchronized.hpp" #include "utils/synchronized.hpp"
namespace memgraph::utils::license { namespace memgraph::license {
namespace { namespace {
inline constexpr std::string_view license_key_prefix = "mglk-"; inline constexpr std::string_view license_key_prefix = "mglk-";
@ -69,6 +71,17 @@ LicenseCheckResult IsValidLicenseInternal(const License &license, const std::str
} }
} // namespace } // 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) { void RegisterLicenseSettings(LicenseChecker &license_checker, utils::Settings &settings) {
settings.RegisterSetting(std::string{kEnterpriseLicenseSettingKey}, "", settings.RegisterSetting(std::string{kEnterpriseLicenseSettingKey}, "",
[&] { license_checker.RevalidateLicense(settings); }); [&] { license_checker.RevalidateLicense(settings); });
@ -81,7 +94,7 @@ LicenseChecker global_license_checker;
LicenseChecker::~LicenseChecker() { scheduler_.Stop(); } 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_) { if (license_info_override_) {
spdlog::warn("Ignoring license info stored in the settings because a different source was specified."); spdlog::warn("Ignoring license info stored in the settings because a different source was specified.");
return *license_info_override_; 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) { 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); RevalidateLicense(license_info.first, license_info.second);
} }
@ -117,18 +130,7 @@ void LicenseChecker::RevalidateLicense(const std::string &license_key, const std
return; return;
} }
struct PreviousLicenseInfo { auto locked_previous_license_info_ptr = previous_license_info_.Lock();
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 = *locked_previous_license_info_ptr; auto &locked_previous_license_info = *locked_previous_license_info_ptr;
const bool same_license_info = locked_previous_license_info && const bool same_license_info = locked_previous_license_info &&
locked_previous_license_info->license_key == license_key && 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); 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) { if (!maybe_license) {
spdlog::warn(LicenseCheckErrorToString(LicenseCheckError::INVALID_LICENSE_KEY_STRING, "Enterprise features")); spdlog::warn(LicenseCheckErrorToString(LicenseCheckError::INVALID_LICENSE_KEY_STRING, "Enterprise features"));
is_valid_.store(false, std::memory_order_relaxed); 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")); spdlog::warn(LicenseCheckErrorToString(license_check_result.GetError(), "Enterprise features"));
is_valid_.store(false, std::memory_order_relaxed); is_valid_.store(false, std::memory_order_relaxed);
locked_previous_license_info->is_valid = false; locked_previous_license_info->is_valid = false;
license_type_ = maybe_license->type;
set_memory_limit(0); set_memory_limit(0);
return; return;
} }
if (!same_license_info) { 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); is_valid_.store(true, std::memory_order_relaxed);
locked_previous_license_info->is_valid = true; locked_previous_license_info->is_valid = true;
set_memory_limit(maybe_license->memory_limit); 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; enterprise_enabled_ = true;
is_valid_.store(true, std::memory_order_relaxed); 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() { void LicenseChecker::CheckEnvLicense() {
@ -216,20 +226,26 @@ std::string LicenseCheckErrorToString(LicenseCheckError error, const std::string
"following query:\n" "following query:\n"
"SET DATABASE SETTING \"enterprise.license\" TO \"your-license-key\"", "SET DATABASE SETTING \"enterprise.license\" TO \"your-license-key\"",
feature); 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]] { if (enterprise_enabled_) [[unlikely]] {
return {}; return {};
} }
const auto license_info = GetLicenseInfo(settings); const auto license_info = ExtractLicenseInfo(settings);
const auto maybe_license = GetLicense(license_info.first); const auto maybe_license = GetLicense(license_info.first);
if (!maybe_license) { if (!maybe_license) {
return LicenseCheckError::INVALID_LICENSE_KEY_STRING; return LicenseCheckError::INVALID_LICENSE_KEY_STRING;
} }
if (maybe_license->type != LicenseType::ENTERPRISE) {
return LicenseCheckError::NOT_ENTERPRISE_LICENSE;
}
return IsValidLicenseInternal(*maybe_license, license_info.second); 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); }); 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::string Encode(const License &license) {
std::vector<uint8_t> buffer; std::vector<uint8_t> buffer;
@ -252,9 +274,10 @@ std::string Encode(const License &license) {
slk::Save(license.organization_name, &builder); slk::Save(license.organization_name, &builder);
slk::Save(license.valid_until, &builder); slk::Save(license.valid_until, &builder);
slk::Save(license.memory_limit, &builder); slk::Save(license.memory_limit, &builder);
slk::Save(utils::UnderlyingCast(license.type), &builder);
builder.Finalize(); 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) { 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> { const auto decoded = std::invoke([license_key]() -> std::optional<std::string> {
try { try {
return base64_decode(license_key); return utils::base64_decode(license_key);
} catch (const std::runtime_error & /*exception*/) { } catch (const std::runtime_error & /*exception*/) {
return std::nullopt; return std::nullopt;
} }
@ -284,10 +307,12 @@ std::optional<License> Decode(std::string_view license_key) {
slk::Load(&valid_until, &reader); slk::Load(&valid_until, &reader);
int64_t memory_limit{0}; int64_t memory_limit{0};
slk::Load(&memory_limit, &reader); 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) { } catch (const slk::SlkReaderException &e) {
return std::nullopt; return std::nullopt;
} }
} }
} // namespace memgraph::utils::license } // namespace memgraph::license

View File

@ -12,26 +12,57 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <optional>
#include <string> #include <string>
#include "utils/result.hpp" #include "utils/result.hpp"
#include "utils/scheduler.hpp" #include "utils/scheduler.hpp"
#include "utils/settings.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 { 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; std::string organization_name;
int64_t valid_until; int64_t valid_until;
int64_t memory_limit; int64_t memory_limit;
LicenseType type;
bool operator==(const License &) const = default; 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 kEnterpriseLicenseSettingKey = "enterprise.license";
inline constexpr std::string_view kOrganizationNameSettingKey = "organization.name"; 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); std::string LicenseCheckErrorToString(LicenseCheckError error, std::string_view feature);
@ -49,19 +80,25 @@ struct LicenseChecker {
void CheckEnvLicense(); void CheckEnvLicense();
void SetLicenseInfoOverride(std::string license_key, std::string organization_name); void SetLicenseInfoOverride(std::string license_key, std::string organization_name);
void EnableTesting(); void EnableTesting(LicenseType license_type = LicenseType::ENTERPRISE);
LicenseCheckResult IsValidLicense(const utils::Settings &settings) const; // Checks if license is valid and if enterprise is enabled
bool IsValidLicenseFast() const; LicenseCheckResult IsEnterpriseValid(const utils::Settings &settings) const;
bool IsEnterpriseValidFast() const;
void StartBackgroundLicenseChecker(const utils::Settings &settings); void StartBackgroundLicenseChecker(const utils::Settings &settings);
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &GetLicenseInfo();
private: 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 utils::Settings &settings);
void RevalidateLicense(const std::string &license_key, const std::string &organization_name); void RevalidateLicense(const std::string &license_key, const std::string &organization_name);
std::optional<std::pair<std::string, std::string>> license_info_override_; 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}; bool enterprise_enabled_{false};
std::atomic<bool> is_valid_{false}; std::atomic<bool> is_valid_{false};
LicenseType license_type_;
utils::Scheduler scheduler_; utils::Scheduler scheduler_;
friend void RegisterLicenseSettings(LicenseChecker &license_checker, utils::Settings &settings); 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) // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern LicenseChecker global_license_checker; extern LicenseChecker global_license_checker;
} // namespace memgraph::utils::license } // namespace memgraph::license

View 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

View 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

View File

@ -40,6 +40,8 @@
#include "glue/auth_checker.hpp" #include "glue/auth_checker.hpp"
#include "glue/auth_handler.hpp" #include "glue/auth_handler.hpp"
#include "helpers.hpp" #include "helpers.hpp"
#include "license/license.hpp"
#include "license/license_sender.hpp"
#include "py/py.hpp" #include "py/py.hpp"
#include "query/auth_checker.hpp" #include "query/auth_checker.hpp"
#include "query/discard_value_stream.hpp" #include "query/discard_value_stream.hpp"
@ -57,7 +59,6 @@
#include "utils/event_counter.hpp" #include "utils/event_counter.hpp"
#include "utils/file.hpp" #include "utils/file.hpp"
#include "utils/flag_validation.hpp" #include "utils/flag_validation.hpp"
#include "utils/license.hpp"
#include "utils/logging.hpp" #include "utils/logging.hpp"
#include "utils/memory_tracker.hpp" #include "utils/memory_tracker.hpp"
#include "utils/message.hpp" #include "utils/message.hpp"
@ -68,6 +69,7 @@
#include "utils/string.hpp" #include "utils/string.hpp"
#include "utils/synchronized.hpp" #include "utils/synchronized.hpp"
#include "utils/sysinfo/memory.hpp" #include "utils/sysinfo/memory.hpp"
#include "utils/system_info.hpp"
#include "utils/terminate_handler.hpp" #include "utils/terminate_handler.hpp"
#include "version.hpp" #include "version.hpp"
@ -506,7 +508,7 @@ class BoltSession final : public memgraph::communication::bolt::Session<memgraph
username = &user_->username(); username = &user_->username();
} }
#ifdef MG_ENTERPRISE #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, audit_log_->Record(endpoint_.address().to_string(), user_ ? *username : "", query,
memgraph::storage::PropertyValue(params_pv)); 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(); }); memgraph::utils::OnScopeExit settings_finalizer([&] { memgraph::utils::global_settings.Finalize(); });
// register all runtime settings // register all runtime settings
memgraph::utils::license::RegisterLicenseSettings(memgraph::utils::license::global_license_checker, memgraph::license::RegisterLicenseSettings(memgraph::license::global_license_checker,
memgraph::utils::global_settings); 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()) { 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 // All enterprise features should be constructed before the main database
// storage. This will cause them to be destructed *after* 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, ServerT server(server_endpoint, &session_data, &context, FLAGS_bolt_session_inactivity_timeout, service_name,
FLAGS_bolt_num_workers); 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 // Setup telemetry
static constexpr auto telemetry_server{"https://telemetry.memgraph.com/88b5e7e8-746a-11e8-9f85-538a9e9690cc/"};
std::optional<memgraph::telemetry::Telemetry> telemetry; std::optional<memgraph::telemetry::Telemetry> telemetry;
if (FLAGS_telemetry_enabled) { if (FLAGS_telemetry_enabled) {
telemetry.emplace("https://telemetry.memgraph.com/88b5e7e8-746a-11e8-9f85-538a9e9690cc/", telemetry.emplace(telemetry_server, data_directory / "telemetry", run_id, machine_id, std::chrono::minutes(10));
data_directory / "telemetry", std::chrono::minutes(10));
session_data.run_id = telemetry->GetRunId();
telemetry->AddCollector("storage", [&db]() -> nlohmann::json { telemetry->AddCollector("storage", [&db]() -> nlohmann::json {
auto info = db.GetInfo(); auto info = db.GetInfo();
return {{"vertices", info.vertex_count}, {"edges", info.edge_count}}; 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(); 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::SafeAuth websocket_auth{&auth};
memgraph::communication::websocket::Server websocket_server{ memgraph::communication::websocket::Server websocket_server{

View File

@ -25,6 +25,7 @@
#include "auth/models.hpp" #include "auth/models.hpp"
#include "glue/communication.hpp" #include "glue/communication.hpp"
#include "license/license.hpp"
#include "memory/memory_control.hpp" #include "memory/memory_control.hpp"
#include "query/constants.hpp" #include "query/constants.hpp"
#include "query/context.hpp" #include "query/context.hpp"
@ -54,7 +55,6 @@
#include "utils/event_counter.hpp" #include "utils/event_counter.hpp"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
#include "utils/flag_validation.hpp" #include "utils/flag_validation.hpp"
#include "utils/license.hpp"
#include "utils/likely.hpp" #include "utils/likely.hpp"
#include "utils/logging.hpp" #include "utils/logging.hpp"
#include "utils/memory.hpp" #include "utils/memory.hpp"
@ -299,7 +299,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa
Callback callback; 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{ static const std::unordered_set enterprise_only_methods{
AuthQuery::Action::CREATE_ROLE, AuthQuery::Action::DROP_ROLE, AuthQuery::Action::SET_ROLE, 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_)) { if (license_check_result.HasError() && enterprise_only_methods.contains(auth_query->action_)) {
throw utils::BasicException( 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_) { 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.properties = NamesToProperties(plan->ast_storage().properties_, dba);
ctx_.evaluation_context.labels = NamesToLabels(plan->ast_storage().labels_, dba); ctx_.evaluation_context.labels = NamesToLabels(plan->ast_storage().labels_, dba);
#ifdef MG_ENTERPRISE #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); ctx_.auth_checker = interpreter_context->auth_checker->GetFineGrainedAuthChecker(*username, dba);
} }
#endif #endif

View File

@ -27,6 +27,7 @@
#include <cppitertools/imap.hpp> #include <cppitertools/imap.hpp>
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "license/license.hpp"
#include "query/auth_checker.hpp" #include "query/auth_checker.hpp"
#include "query/context.hpp" #include "query/context.hpp"
#include "query/db_accessor.hpp" #include "query/db_accessor.hpp"
@ -47,7 +48,6 @@
#include "utils/event_counter.hpp" #include "utils/event_counter.hpp"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
#include "utils/fnv.hpp" #include "utils/fnv.hpp"
#include "utils/license.hpp"
#include "utils/likely.hpp" #include "utils/likely.hpp"
#include "utils/logging.hpp" #include "utils/logging.hpp"
#include "utils/memory.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) { bool CreateNode::CreateNodeCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("CreateNode"); SCOPED_PROFILE_OP("CreateNode");
#ifdef MG_ENTERPRISE #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, !context.auth_checker->Has(self_.node_info_.labels,
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
throw QueryRuntimeException("Vertex not created due to not having enough permission!"); 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; if (!input_cursor_->Pull(frame, context)) return false;
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (utils::license::global_license_checker.IsValidLicenseFast()) { if (license::global_license_checker.IsEnterpriseValidFast()) {
const auto fine_grained_permission = self_.existing_node_ const auto fine_grained_permission = self_.existing_node_
? memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE ? memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE
@ -433,8 +433,7 @@ class ScanAllCursor : public Cursor {
vertices_it_.emplace(vertices_.value().begin()); vertices_it_.emplace(vertices_.value().begin());
} }
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker && !FindNextVertex(context)) {
!FindNextVertex(context)) {
return false; return false;
} }
#endif #endif
@ -731,7 +730,7 @@ bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) {
if (in_edges_ && *in_edges_it_ != in_edges_->end()) { if (in_edges_ && *in_edges_it_ != in_edges_->end()) {
auto edge = *(*in_edges_it_)++; auto edge = *(*in_edges_it_)++;
#ifdef MG_ENTERPRISE #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, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge.From(), self_.view_, context.auth_checker->Has(edge.From(), self_.view_,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
@ -752,7 +751,7 @@ bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) {
// already done in the block above // already done in the block above
if (self_.common_.direction == EdgeAtom::Direction::BOTH && edge.IsCycle()) continue; if (self_.common_.direction == EdgeAtom::Direction::BOTH && edge.IsCycle()) continue;
#ifdef MG_ENTERPRISE #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, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge.To(), self_.view_, context.auth_checker->Has(edge.To(), self_.view_,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
@ -1089,7 +1088,7 @@ class ExpandVariableCursor : public Cursor {
VertexAccessor current_vertex = VertexAccessor current_vertex =
current_edge.second == EdgeAtom::Direction::IN ? current_edge.first.From() : current_edge.first.To(); current_edge.second == EdgeAtom::Direction::IN ? current_edge.first.From() : current_edge.first.To();
#ifdef MG_ENTERPRISE #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_edge.first, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(current_vertex, storage::View::OLD, context.auth_checker->Has(current_vertex, storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { 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)); auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : out_edges) { for (const auto &edge : out_edges) {
#ifdef MG_ENTERPRISE #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, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge.To(), storage::View::OLD, context.auth_checker->Has(edge.To(), storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { 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)); auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : in_edges) { for (const auto &edge : in_edges) {
#ifdef MG_ENTERPRISE #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, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge.From(), storage::View::OLD, context.auth_checker->Has(edge.From(), storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { 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)); auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : out_edges) { for (const auto &edge : out_edges) {
#ifdef MG_ENTERPRISE #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, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge.To(), storage::View::OLD, context.auth_checker->Has(edge.To(), storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { 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)); auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : in_edges) { for (const auto &edge : in_edges) {
#ifdef MG_ENTERPRISE #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, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge.From(), storage::View::OLD, context.auth_checker->Has(edge.From(), storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { 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 we already processed the given vertex it doesn't get expanded
if (processed_.find(vertex) != processed_.end()) return; if (processed_.find(vertex) != processed_.end()) return;
#ifdef MG_ENTERPRISE #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, !(context.auth_checker->Has(vertex, storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge, 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) { int64_t depth) {
auto *memory = evaluator.GetMemoryResource(); auto *memory = evaluator.GetMemoryResource();
#ifdef MG_ENTERPRISE #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, !(context.auth_checker->Has(vertex, storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge, 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)); auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : out_edges) { for (const auto &edge : out_edges) {
#ifdef MG_ENTERPRISE #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, !(context.auth_checker->Has(edge.To(), storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge, 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)); auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : in_edges) { for (const auto &edge : in_edges) {
#ifdef MG_ENTERPRISE #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, !(context.auth_checker->Has(edge.From(), storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
context.auth_checker->Has(edge, 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); 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(); 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; frame[self_.total_weight_.value()] = current_weight;
if (next_edges_.find({next_vertex, traversal_stack_.size()}) != next_edges_.end()) { 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; 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; return true;
} }
@ -2366,7 +2373,7 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) {
if (expression_result.type() == TypedValue::Type::Edge) { if (expression_result.type() == TypedValue::Type::Edge) {
auto &ea = expression_result.ValueEdge(); auto &ea = expression_result.ValueEdge();
#ifdef MG_ENTERPRISE #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, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE) &&
context.auth_checker->Has(ea.To(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE) && 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))) { 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: { case TypedValue::Type::Vertex: {
auto &va = expression_result.ValueVertex(); auto &va = expression_result.ValueVertex();
#ifdef MG_ENTERPRISE #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)) { !context.auth_checker->Has(va, storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
throw QueryRuntimeException("Vertex not deleted due to not having enough permission!"); 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()) { switch (lhs.type()) {
case TypedValue::Type::Vertex: { case TypedValue::Type::Vertex: {
#ifdef MG_ENTERPRISE #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, !context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw QueryRuntimeException("Vertex property not set due to not having enough permission!"); 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: { case TypedValue::Type::Edge: {
#ifdef MG_ENTERPRISE #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)) { !context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw QueryRuntimeException("Edge property not set due to not having enough permission!"); 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()) { switch (lhs.type()) {
case TypedValue::Type::Vertex: case TypedValue::Type::Vertex:
#ifdef MG_ENTERPRISE #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, !context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw QueryRuntimeException("Vertex properties not set due to not having enough permission!"); 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; break;
case TypedValue::Type::Edge: case TypedValue::Type::Edge:
#ifdef MG_ENTERPRISE #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)) { !context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw QueryRuntimeException("Edge properties not set due to not having enough permission!"); 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"); SCOPED_PROFILE_OP("SetLabels");
#ifdef MG_ENTERPRISE #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)) { !context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
throw QueryRuntimeException("Couldn't set label due to not having enough permission!"); 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(); auto &vertex = vertex_value.ValueVertex();
#ifdef MG_ENTERPRISE #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, !context.auth_checker->Has(vertex, storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw QueryRuntimeException("Couldn't set label due to not having enough permission!"); 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()) { switch (lhs.type()) {
case TypedValue::Type::Vertex: case TypedValue::Type::Vertex:
#ifdef MG_ENTERPRISE #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, !context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw QueryRuntimeException("Vertex property not removed due to not having enough permission!"); throw QueryRuntimeException("Vertex property not removed due to not having enough permission!");
@ -2893,7 +2900,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, ExecutionContext &
break; break;
case TypedValue::Type::Edge: case TypedValue::Type::Edge:
#ifdef MG_ENTERPRISE #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)) { !context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw QueryRuntimeException("Edge property not removed due to not having enough permission!"); 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"); SCOPED_PROFILE_OP("RemoveLabels");
#ifdef MG_ENTERPRISE #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)) { !context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
throw QueryRuntimeException("Couldn't remove label due to not having enough permission!"); 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(); auto &vertex = vertex_value.ValueVertex();
#ifdef MG_ENTERPRISE #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, !context.auth_checker->Has(vertex, storage::View::OLD,
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw QueryRuntimeException("Couldn't remove label due to not having enough permission!"); throw QueryRuntimeException("Couldn't remove label due to not having enough permission!");

View File

@ -22,6 +22,7 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include "license/license.hpp"
#include "mg_procedure.h" #include "mg_procedure.h"
#include "module.hpp" #include "module.hpp"
#include "query/frontend/ast/ast.hpp" #include "query/frontend/ast/ast.hpp"
@ -32,7 +33,6 @@
#include "storage/v2/view.hpp" #include "storage/v2/view.hpp"
#include "utils/algorithm.hpp" #include "utils/algorithm.hpp"
#include "utils/concepts.hpp" #include "utils/concepts.hpp"
#include "utils/license.hpp"
#include "utils/logging.hpp" #include "utils/logging.hpp"
#include "utils/math.hpp" #include "utils/math.hpp"
#include "utils/memory.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; auto *ctx = v->graph->ctx;
#ifdef MG_ENTERPRISE #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, !ctx->auth_checker->Has(v->getImpl(), v->graph->view,
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw AuthorizationException{"Insufficient permissions for setting a property on vertex!"}; 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); const auto label_id = std::visit([label](auto *impl) { return impl->NameToLabel(label.name); }, v->graph->impl);
#ifdef MG_ENTERPRISE #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, !(ctx->auth_checker->Has(v->getImpl(), v->graph->view,
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) && memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
ctx->auth_checker->Has({label_id}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) { 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); const auto label_id = std::visit([&label](auto *impl) { return impl->NameToLabel(label.name); }, v->graph->impl);
#ifdef MG_ENTERPRISE #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, !(ctx->auth_checker->Has(v->getImpl(), v->graph->view,
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) && memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
ctx->auth_checker->Has({label_id}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) { 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.emplace(std::move(*maybe_edges));
it->in_it.emplace(it->in->begin()); it->in_it.emplace(it->in->begin());
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
NextPermittedEdge(*it, true); NextPermittedEdge(*it, true);
} }
#endif #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()); it->out_it.emplace(it->out->begin());
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
NextPermittedEdge(*it, false); NextPermittedEdge(*it, false);
} }
#endif #endif
@ -2099,7 +2099,7 @@ mgp_error mgp_edges_iterator_next(mgp_edges_iterator *it, mgp_edge **result) {
++*impl_it; ++*impl_it;
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
NextPermittedEdge(*it, for_in); NextPermittedEdge(*it, for_in);
} }
#endif #endif
@ -2124,10 +2124,7 @@ mgp_error mgp_edges_iterator_next(mgp_edges_iterator *it, mgp_edge **result) {
return &*it->current_e; return &*it->current_e;
}; };
if (it->in_it) { if (it->in_it) {
auto *result = next(true); return next(true);
if (result != nullptr) {
return result;
}
} }
return next(false); 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; auto *ctx = e->from.graph->ctx;
#ifdef MG_ENTERPRISE #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)) { !ctx->auth_checker->Has(e->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
throw AuthorizationException{"Insufficient permissions for setting a property on edge!"}; 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 * { [=]() -> mgp_vertex * {
#ifdef MG_ENTERPRISE #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 &&
!graph->ctx->auth_checker->HasGlobalPrivilegeOnVertices( !graph->ctx->auth_checker->HasGlobalPrivilegeOnVertices(
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { 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; auto *ctx = graph->ctx;
#ifdef MG_ENTERPRISE #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, !ctx->auth_checker->Has(vertex->getImpl(), graph->view,
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
throw AuthorizationException{"Insufficient permissions for deleting a vertex!"}; 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([=] { return WrapExceptions([=] {
auto *ctx = graph->ctx; auto *ctx = graph->ctx;
#ifdef MG_ENTERPRISE #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, !ctx->auth_checker->Has(vertex->getImpl(), graph->view,
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
throw AuthorizationException{"Insufficient permissions for deleting a vertex!"}; 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 #ifdef MG_ENTERPRISE
const auto edge_id = const auto edge_id =
std::visit([type](auto *impl) { return impl->NameToEdgeType(type.name); }, from->graph->impl); 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)) { !ctx->auth_checker->Has(edge_id, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
throw AuthorizationException{"Insufficient permissions for creating edges!"}; 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([=] { return WrapExceptions([=] {
auto *ctx = graph->ctx; auto *ctx = graph->ctx;
#ifdef MG_ENTERPRISE #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)) { !ctx->auth_checker->Has(edge->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
throw AuthorizationException{"Insufficient permissions for deleting an edge!"}; 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)), vertices(std::visit([graph](auto *impl) { return impl->Vertices(graph->view); }, graph->impl)),
current_it(vertices.begin()) { current_it(vertices.begin()) {
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
NextPermitted(*this); NextPermitted(*this);
} }
#endif #endif
@ -2630,7 +2627,7 @@ mgp_error mgp_vertices_iterator_next(mgp_vertices_iterator *it, mgp_vertex **res
++it->current_it; ++it->current_it;
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
NextPermitted(*it); NextPermitted(*it);
} }
#endif #endif

View File

@ -1,12 +1,12 @@
set(telemetry_src_files set(telemetry_src_files
collectors.cpp collectors.cpp
telemetry.cpp telemetry.cpp)
system_info.cpp)
add_library(telemetry_lib STATIC ${telemetry_src_files}) add_library(mg-telemetry STATIC ${telemetry_src_files})
target_link_libraries(telemetry_lib mg-requests mg-kvstore mg-utils) target_link_libraries(mg-telemetry mg-requests mg-kvstore mg-utils)
option(MG_TELEMETRY_ID_OVERRIDE "Override for the telemetry ID" STRING) 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}") 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() endif()

View File

@ -17,38 +17,24 @@
#include "requests/requests.hpp" #include "requests/requests.hpp"
#include "telemetry/collectors.hpp" #include "telemetry/collectors.hpp"
#include "telemetry/system_info.hpp"
#include "utils/file.hpp" #include "utils/file.hpp"
#include "utils/logging.hpp" #include "utils/logging.hpp"
#include "utils/system_info.hpp"
#include "utils/timestamp.hpp" #include "utils/timestamp.hpp"
#include "utils/uuid.hpp" #include "utils/uuid.hpp"
namespace memgraph::telemetry { 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) std::chrono::duration<int64_t> refresh_interval, const uint64_t send_every_n)
: url_(std::move(url)), : url_(std::move(url)),
uuid_(utils::GenerateUUID()), uuid_(uuid),
machine_id_(GetMachineId()), machine_id_(machine_id),
send_every_n_(send_every_n), send_every_n_(send_every_n),
storage_(std::move(storage_directory)) { storage_(std::move(storage_directory)) {
StoreData("startup", GetSystemInfo()); StoreData("startup", utils::GetSystemInfo());
AddCollector("resources", GetResourceUsage); AddCollector("resources", GetResourceUsage);
AddCollector("uptime", [&]() -> nlohmann::json { return GetUptime(); }); AddCollector("uptime", [&]() -> nlohmann::json { return GetUptime(); });
scheduler_.Run("Telemetry", refresh_interval, [&] { CollectData(); }); 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); collectors_.emplace_back(name, func);
} }
std::string Telemetry::GetRunId() const { return uuid_; }
Telemetry::~Telemetry() { Telemetry::~Telemetry() {
scheduler_.Stop(); scheduler_.Stop();
CollectData("shutdown"); CollectData("shutdown");
} }
void Telemetry::StoreData(const nlohmann::json &event, const nlohmann::json &data) { void Telemetry::StoreData(const nlohmann::json &event, const nlohmann::json &data) {
nlohmann::json payload = {{"run_id", uuid_}, nlohmann::json payload = {
{"machine_id", machine_id_}, {"run_id", uuid_}, {"type", "telemetry"}, {"machine_id", machine_id_},
{"event", event}, {"event", event}, {"data", data}, {"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}};
{"data", data},
{"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}};
storage_.Put(fmt::format("{}:{}", uuid_, event.dump()), payload.dump()); storage_.Put(fmt::format("{}:{}", uuid_, event.dump()), payload.dump());
} }

View File

@ -26,7 +26,7 @@ namespace memgraph::telemetry {
* This class implements the telemetry collector service. It periodically scapes * This class implements the telemetry collector service. It periodically scapes
* all registered collectors and stores their data. With periodically scraping * all registered collectors and stores their data. With periodically scraping
* the collectors the service collects machine information in the constructor * 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 * 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 no internet connection the data will be sent when the internet connection
* is reestablished. If there is an issue with the internet connection that * is reestablished. If there is an issue with the internet connection that
@ -34,14 +34,11 @@ namespace memgraph::telemetry {
*/ */
class Telemetry final { class Telemetry final {
public: 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); 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); 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();
Telemetry(const Telemetry &) = delete; Telemetry(const Telemetry &) = delete;

View File

@ -14,6 +14,7 @@ set(utils_src_files
thread.cpp thread.cpp
thread_pool.cpp thread_pool.cpp
tsc.cpp tsc.cpp
system_info.cpp
uuid.cpp) uuid.cpp)
find_package(Boost REQUIRED) find_package(Boost REQUIRED)
@ -23,16 +24,10 @@ find_package(Threads REQUIRED)
add_library(mg-utils STATIC ${utils_src_files}) 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 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 set(settings_src_files
settings.cpp) settings.cpp)
add_library(mg-settings STATIC ${settings_src_files}) add_library(mg-settings STATIC ${settings_src_files})
target_link_libraries(mg-settings mg-kvstore mg-slk mg-utils) 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)

View File

@ -43,7 +43,7 @@ inline uint64_t GetMemoryUsage() {
pid_t pid = getpid(); pid_t pid = getpid();
uint64_t memory = 0; uint64_t memory = 0;
auto statm_data = utils::ReadLines(fmt::format("/proc/{}/statm", pid)); 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]); auto split = utils::Split(statm_data[0]);
if (split.size() >= 2) { if (split.size() >= 2) {
memory = std::stoull(split[1]) * sysconf(_SC_PAGESIZE); memory = std::stoull(split[1]) * sysconf(_SC_PAGESIZE);

View File

@ -9,56 +9,35 @@
// by the Apache License, Version 2.0, included in the file // by the Apache License, Version 2.0, included in the file
// licenses/APL.txt. // licenses/APL.txt.
#include "telemetry/system_info.hpp" #include "utils/system_info.hpp"
#include <string> #include <string>
#include <sys/utsname.h>
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <sys/utsname.h>
#include "utils/file.hpp" #include "utils/file.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
namespace memgraph::telemetry { namespace memgraph::utils {
const nlohmann::json GetSystemInfo() { std::string GetMachineId() {
// Get `uname`. #ifdef MG_TELEMETRY_ID_OVERRIDE
struct utsname info; return MG_TELEMETRY_ID_OVERRIDE;
if (uname(&info) != 0) return {}; #else
// We assume we're on linux and we need to read the machine id from /etc/machine-id
// Parse `/etc/os-release`. const auto machine_id_lines = memgraph::utils::ReadLines("/etc/machine-id");
std::string os_name, os_version, os_full; if (machine_id_lines.size() != 1) {
auto os_data = utils::ReadLines("/etc/os-release"); return "UNKNOWN";
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]);
}
} }
return machine_id_lines[0];
#endif
}
MemoryInfo GetMemoryInfo() {
// Parse `/proc/meminfo`. // Parse `/proc/meminfo`.
nlohmann::json ret; uint64_t memory{0};
uint64_t memory = 0, swap = 0; uint64_t swap{0};
auto mem_data = utils::ReadLines("/proc/meminfo"); auto mem_data = utils::ReadLines("/proc/meminfo");
for (auto &row : mem_data) { for (auto &row : mem_data) {
auto tmp = utils::Trim(row); auto tmp = utils::Trim(row);
@ -74,15 +53,55 @@ const nlohmann::json GetSystemInfo() {
} }
memory *= 1024; memory *= 1024;
swap *= 1024; swap *= 1024;
return {memory, swap};
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()}};
} }
} // 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

View File

@ -11,16 +11,33 @@
#pragma once #pragma once
#include <cstdint>
#include <string>
#include <json/json.hpp> #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.). * (eg. operating system name, cpu information, memory information, etc.).
*/ */
const nlohmann::json GetSystemInfo(); nlohmann::json GetSystemInfo();
} // namespace memgraph::telemetry } // namespace memgraph::utils

View File

@ -13,24 +13,6 @@ add_subdirectory(auth)
# lba test binaries # lba test binaries
add_subdirectory(fine_grained_access) 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 # audit test binaries
add_subdirectory(audit) add_subdirectory(audit)
@ -39,3 +21,6 @@ add_subdirectory(ldap)
# mg_import_csv test binaries # mg_import_csv test binaries
add_subdirectory(mg_import_csv) add_subdirectory(mg_import_csv)
# license_check test binaries
add_subdirectory(license_info)

View 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)

View 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;
}

View 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()

View 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()

View File

@ -3,4 +3,4 @@ set(client_target_name ${target_name}__client)
add_executable(${client_target_name} client.cpp) add_executable(${client_target_name} client.cpp)
set_target_properties(${client_target_name} PROPERTIES OUTPUT_NAME client) 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)

View File

@ -13,6 +13,8 @@
#include "requests/requests.hpp" #include "requests/requests.hpp"
#include "telemetry/telemetry.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_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."); 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); gflags::ParseCommandLineFlags(&argc, &argv, true);
memgraph::requests::Init(); memgraph::requests::Init();
memgraph::telemetry::Telemetry telemetry(FLAGS_endpoint, FLAGS_storage_directory, memgraph::telemetry::Telemetry telemetry(FLAGS_endpoint, FLAGS_storage_directory, memgraph::utils::GenerateUUID(),
std::chrono::seconds(FLAGS_interval), 1); memgraph::utils::GetMachineId(), std::chrono::seconds(FLAGS_interval), 1);
uint64_t counter = 0; uint64_t counter = 0;
telemetry.AddCollector("db", [&counter]() -> nlohmann::json { telemetry.AddCollector("db", [&counter]() -> nlohmann::json {

View File

@ -36,8 +36,7 @@ def execute_test(**kwargs):
timeout = duration * 2 if "hang" not in kwargs else duration * 2 + 60 timeout = duration * 2 if "hang" not in kwargs else duration * 2 + 60
success = False success = False
server_args = [server_binary, "--interval", interval, server_args = [server_binary, "--interval", interval, "--duration", duration]
"--duration", duration]
for flag, value in kwargs.items(): for flag, value in kwargs.items():
flag = "--" + flag.replace("_", "-") flag = "--" + flag.replace("_", "-")
# We handle boolean flags here. The type of value must be `bool`, and # We handle boolean flags here. The type of value must be `bool`, and
@ -48,9 +47,15 @@ def execute_test(**kwargs):
else: else:
server_args.extend([flag, value]) server_args.extend([flag, value])
client_args = [client_binary, "--interval", interval, client_args = [
"--duration", duration, client_binary,
"--storage-directory", storage_directory] "--interval",
interval,
"--duration",
duration,
"--storage-directory",
storage_directory,
]
if endpoint: if endpoint:
client_args.extend(["--endpoint", endpoint]) client_args.extend(["--endpoint", endpoint])
@ -61,8 +66,7 @@ def execute_test(**kwargs):
assert server.poll() is None, "Server process died prematurely!" assert server.poll() is None, "Server process died prematurely!"
try: try:
subprocess.run(list(map(str, client_args)), timeout=timeout, subprocess.run(list(map(str, client_args)), timeout=timeout, check=True)
check=True)
finally: finally:
if server is None: if server is None:
success = True success = True
@ -88,16 +92,14 @@ TESTS = [
{"endpoint": "http://127.0.0.1:9000/nonexistant/", "no_check": True}, {"endpoint": "http://127.0.0.1:9000/nonexistant/", "no_check": True},
{"start_server": False}, {"start_server": False},
{"startups": 4, "no_check_duration": True}, # the last 3 tests failed {"startups": 4, "no_check_duration": True}, # the last 3 tests failed
# to send any data + this test # to send any data + this test
{"add_garbage": True} {"add_garbage": True},
] ]
if __name__ == "__main__": if __name__ == "__main__":
server_binary = os.path.join(SCRIPT_DIR, "server.py") server_binary = os.path.join(SCRIPT_DIR, "server.py")
client_binary = os.path.join(PROJECT_DIR, "build", "tests", client_binary = os.path.join(PROJECT_DIR, "build", "tests", "integration", "telemetry", "client")
"integration", "telemetry", "client") kvstore_console_binary = os.path.join(PROJECT_DIR, "build", "tests", "manual", "kvstore_console")
kvstore_console_binary = os.path.join(PROJECT_DIR, "build", "tests",
"manual", "kvstore_console")
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--client", default=client_binary) parser.add_argument("--client", default=client_binary)
@ -108,19 +110,17 @@ if __name__ == "__main__":
storage = tempfile.TemporaryDirectory() storage = tempfile.TemporaryDirectory()
for test in TESTS: for test in TESTS:
print("\033[1;36m~~ Executing test with arguments:", print("\033[1;36m~~ Executing test with arguments:", json.dumps(test, sort_keys=True), "~~\033[0m")
json.dumps(test, sort_keys=True), "~~\033[0m")
if test.pop("add_garbage", False): if test.pop("add_garbage", False):
proc = subprocess.Popen([args.kvstore_console, "--path", proc = subprocess.Popen(
storage.name], stdin=subprocess.PIPE, [args.kvstore_console, "--path", storage.name], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL
stdout=subprocess.DEVNULL) )
proc.communicate("put garbage garbage".encode("utf-8")) proc.communicate("put garbage garbage".encode("utf-8"))
assert proc.wait() == 0 assert proc.wait() == 0
try: try:
success = execute_test(client=args.client, server=args.server, success = execute_test(client=args.client, server=args.server, storage=storage.name, **test)
storage=storage.name, **test)
except Exception as e: except Exception as e:
print("\033[1;33m", e, "\033[0m", sep="") print("\033[1;33m", e, "\033[0m", sep="")
success = False success = False

View File

@ -12,13 +12,12 @@
# licenses/APL.txt. # licenses/APL.txt.
import argparse import argparse
import itertools
import json import json
import os import os
import signal import signal
import sys import sys
import time import time
import itertools
from http.server import BaseHTTPRequestHandler, HTTPServer from http.server import BaseHTTPRequestHandler, HTTPServer
@ -46,7 +45,7 @@ def build_handler(storage, args):
assert self.headers["accept"] == "application/json" assert self.headers["accept"] == "application/json"
assert self.headers["content-type"] == "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")) data = json.loads(self.rfile.read(content_len).decode("utf-8"))
if self.path not in [args.path, args.redirect_path]: if self.path not in [args.path, args.redirect_path]:
@ -70,6 +69,7 @@ def build_handler(storage, args):
assert type(item) == dict assert type(item) == dict
assert "event" in item assert "event" in item
assert "run_id" in item assert "run_id" in item
assert "type" in item
assert "machine_id" in item assert "machine_id" in item
assert "data" in item assert "data" in item
assert "timestamp" in item assert "timestamp" in item
@ -188,11 +188,11 @@ if __name__ == "__main__":
startups[-1].append(item) startups[-1].append(item)
# Check that there were the correct number of startups. # 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. # Verify each startup.
for startup in startups: for startup in startups:
verify_storage(startup, args) verify_storage(startup, args)
# machine id has to be same for every run on the same machine # 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

View File

@ -10,11 +10,11 @@
// licenses/APL.txt. // licenses/APL.txt.
#include "communication/result_stream_faker.hpp" #include "communication/result_stream_faker.hpp"
#include "license/license.hpp"
#include "query/config.hpp" #include "query/config.hpp"
#include "query/interpreter.hpp" #include "query/interpreter.hpp"
#include "storage/v2/isolation_level.hpp" #include "storage/v2/isolation_level.hpp"
#include "storage/v2/storage.hpp" #include "storage/v2/storage.hpp"
#include "utils/license.hpp"
#include "utils/on_scope_exit.hpp" #include "utils/on_scope_exit.hpp"
int main(int argc, char *argv[]) { 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"; auto data_directory = std::filesystem::temp_directory_path() / "single_query_test";
memgraph::utils::OnScopeExit([&data_directory] { std::filesystem::remove_all(data_directory); }); 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::InterpreterContext interpreter_context{&db, memgraph::query::InterpreterConfig{}, data_directory};
memgraph::query::Interpreter interpreter{&interpreter_context}; memgraph::query::Interpreter interpreter{&interpreter_context};

View File

@ -269,8 +269,8 @@ target_link_libraries(${test_prefix}utils_csv_parsing mg-utils fmt)
add_unit_test(utils_async_timer.cpp) add_unit_test(utils_async_timer.cpp)
target_link_libraries(${test_prefix}utils_async_timer mg-utils) target_link_libraries(${test_prefix}utils_async_timer mg-utils)
add_unit_test(utils_license.cpp) add_unit_test(license.cpp)
target_link_libraries(${test_prefix}utils_license mg-utils mg-license) target_link_libraries(${test_prefix}license mg-utils mg-license)
add_unit_test(utils_settings.cpp) add_unit_test(utils_settings.cpp)
target_link_libraries(${test_prefix}utils_settings mg-utils mg-settings) target_link_libraries(${test_prefix}utils_settings mg-utils mg-settings)

View File

@ -19,9 +19,9 @@
#include "auth/auth.hpp" #include "auth/auth.hpp"
#include "auth/crypto.hpp" #include "auth/crypto.hpp"
#include "auth/models.hpp" #include "auth/models.hpp"
#include "license/license.hpp"
#include "utils/cast.hpp" #include "utils/cast.hpp"
#include "utils/file.hpp" #include "utils/file.hpp"
#include "utils/license.hpp"
using namespace memgraph::auth; using namespace memgraph::auth;
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -36,7 +36,7 @@ class AuthWithStorage : public ::testing::Test {
FLAGS_auth_password_permit_null = true; FLAGS_auth_password_permit_null = true;
FLAGS_auth_password_strength_regex = ".+"; 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_); } virtual void TearDown() { fs::remove_all(test_folder_); }

View File

@ -15,9 +15,9 @@
#include "auth/models.hpp" #include "auth/models.hpp"
#include "glue/auth_checker.hpp" #include "glue/auth_checker.hpp"
#include "license/license.hpp"
#include "query_plan_common.hpp" #include "query_plan_common.hpp"
#include "storage/v2/view.hpp" #include "storage/v2/view.hpp"
#include "utils/license.hpp"
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
class FineGrainedAuthCheckerFixture : public testing::Test { 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)}; memgraph::query::EdgeAccessor r4{*dba.InsertEdge(&v1, &v3, edge_type_two)};
void SetUp() override { 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(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue()); ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue()); ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());

View File

@ -37,7 +37,7 @@ class AuthQueryHandlerFixture : public testing::Test {
#endif #endif
virtual void SetUp() { virtual void SetUp() {
memgraph::utils::EnsureDir(test_folder_); memgraph::utils::EnsureDir(test_folder_);
memgraph::utils::license::global_license_checker.EnableTesting(); memgraph::license::global_license_checker.EnableTesting();
} }
virtual void TearDown() { virtual void TearDown() {

View File

@ -18,7 +18,7 @@
#include <gtest/internal/gtest-param-util-generated.h> #include <gtest/internal/gtest-param-util-generated.h>
#include "auth/models.hpp" #include "auth/models.hpp"
#include "utils/license.hpp" #include "license/license.hpp"
using namespace memgraph::query; using namespace memgraph::query;
using namespace memgraph::query::plan; using namespace memgraph::query::plan;
@ -80,7 +80,7 @@ class FineGrainedBfsTest
std::tuple<int, int, EdgeAtom::Direction, std::vector<std::string>, bool, FineGrainedTestType>> { std::tuple<int, int, EdgeAtom::Direction, std::vector<std::string>, bool, FineGrainedTestType>> {
public: public:
static void SetUpTestCase() { static void SetUpTestCase() {
memgraph::utils::license::global_license_checker.EnableTesting(); memgraph::license::global_license_checker.EnableTesting();
db_ = std::make_unique<VertexDb>(); db_ = std::make_unique<VertexDb>();
} }
static void TearDownTestCase() { db_ = nullptr; } static void TearDownTestCase() { db_ = nullptr; }

View File

@ -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) { TEST_F(InterpreterTest, CreateLabelIndexInMulticommandTransaction) {
Interpret("BEGIN"); Interpret("BEGIN");
ASSERT_THROW(Interpret("CREATE INDEX ON :X"), memgraph::query::IndexInMulticommandTxException); ASSERT_THROW(Interpret("CREATE INDEX ON :X"), memgraph::query::IndexInMulticommandTxException);

View File

@ -10,8 +10,9 @@
// licenses/APL.txt. // licenses/APL.txt.
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <cstdint>
#include "utils/license.hpp" #include "license/license.hpp"
#include "utils/settings.hpp" #include "utils/settings.hpp"
class LicenseTest : public ::testing::Test { class LicenseTest : public ::testing::Test {
@ -21,7 +22,7 @@ class LicenseTest : public ::testing::Test {
settings->Initialize(settings_directory); settings->Initialize(settings_directory);
license_checker.emplace(); license_checker.emplace();
memgraph::utils::license::RegisterLicenseSettings(*license_checker, *settings); memgraph::license::RegisterLicenseSettings(*license_checker, *settings);
license_checker->StartBackgroundLicenseChecker(*settings); license_checker->StartBackgroundLicenseChecker(*settings);
} }
@ -33,24 +34,25 @@ class LicenseTest : public ::testing::Test {
const std::filesystem::path settings_directory{test_directory / "settings"}; const std::filesystem::path settings_directory{test_directory / "settings"};
void CheckLicenseValidity(const bool expected_valid) { void CheckLicenseValidity(const bool expected_valid) {
ASSERT_EQ(!license_checker->IsValidLicense(*settings).HasError(), expected_valid); ASSERT_EQ(!license_checker->IsEnterpriseValid(*settings).HasError(), expected_valid);
ASSERT_EQ(license_checker->IsValidLicenseFast(), expected_valid); ASSERT_EQ(license_checker->IsEnterpriseValidFast(), expected_valid);
} }
std::optional<memgraph::utils::Settings> settings; 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) { TEST_F(LicenseTest, EncodeDecode) {
const std::array licenses = { const std::array licenses = {
memgraph::utils::license::License{"Organization", 1, 2}, memgraph::license::License{"Organization", 1, 2, memgraph::license::LicenseType::OEM},
memgraph::utils::license::License{"", -1, 0}, memgraph::license::License{"", -1, 0, memgraph::license::LicenseType::ENTERPRISE},
memgraph::utils::license::License{"Some very long name for the organization Ltd", -999, -9999}, memgraph::license::License{"Some very long name for the organization Ltd", -999, -9999,
memgraph::license::LicenseType::ENTERPRISE},
}; };
for (const auto &license : licenses) { for (const auto &license : licenses) {
const auto result = memgraph::utils::license::Encode(license); const auto result = memgraph::license::Encode(license);
auto maybe_license = memgraph::utils::license::Decode(result); auto maybe_license = memgraph::license::Decode(result);
ASSERT_TRUE(maybe_license); ASSERT_TRUE(maybe_license);
ASSERT_EQ(*maybe_license, license); ASSERT_EQ(*maybe_license, license);
} }
@ -69,10 +71,9 @@ TEST_F(LicenseTest, TestingFlag) {
TEST_F(LicenseTest, LicenseOrganizationName) { TEST_F(LicenseTest, LicenseOrganizationName) {
const std::string organization_name{"Memgraph"}; const std::string organization_name{"Memgraph"};
memgraph::utils::license::License license{ memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0};
settings->SetValue("enterprise.license", memgraph::utils::license::Encode(license)); settings->SetValue("enterprise.license", memgraph::license::Encode(license));
settings->SetValue("organization.name", organization_name); settings->SetValue("organization.name", organization_name);
CheckLicenseValidity(true); 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()); std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
const auto delta = std::chrono::seconds(1); const auto delta = std::chrono::seconds(1);
const auto valid_until = now + delta; const auto valid_until = now + delta;
memgraph::utils::license::License license{ memgraph::license::License license{organization_name, valid_until.count(), 0,
.organization_name = organization_name, .valid_until = valid_until.count(), .memory_limit = 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); settings->SetValue("organization.name", organization_name);
CheckLicenseValidity(true); CheckLicenseValidity(true);
std::this_thread::sleep_for(delta + std::chrono::seconds(1)); 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 // We can't check fast checker because it has unknown refresh rate
} }
{ {
SCOPED_TRACE("License with valid_until = 0 is always valid"); SCOPED_TRACE("License with valid_until = 0 is always valid");
memgraph::utils::license::License license{ memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0}; settings->SetValue("enterprise.license", memgraph::license::Encode(license));
settings->SetValue("enterprise.license", memgraph::utils::license::Encode(license));
settings->SetValue("organization.name", organization_name); settings->SetValue("organization.name", organization_name);
CheckLicenseValidity(true); CheckLicenseValidity(true);
} }
@ -116,9 +116,8 @@ TEST_F(LicenseTest, LicenseInfoOverride) {
CheckLicenseValidity(false); CheckLicenseValidity(false);
const std::string organization_name{"Memgraph"}; const std::string organization_name{"Memgraph"};
memgraph::utils::license::License license{ memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0}; const std::string license_key = memgraph::license::Encode(license);
const std::string license_key = memgraph::utils::license::Encode(license);
{ {
SCOPED_TRACE("Checker should use overrides instead of info from the settings"); SCOPED_TRACE("Checker should use overrides instead of info from the settings");
@ -139,3 +138,40 @@ TEST_F(LicenseTest, LicenseInfoOverride) {
CheckLicenseValidity(false); 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);
}
}

View File

@ -20,11 +20,11 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "license/license.hpp"
#include "query/context.hpp" #include "query/context.hpp"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "query/interpret/frame.hpp" #include "query/interpret/frame.hpp"
#include "query/plan/operator.hpp" #include "query/plan/operator.hpp"
#include "utils/license.hpp"
#include "query_plan_common.hpp" #include "query_plan_common.hpp"
#include "storage/v2/id_types.hpp" #include "storage/v2/id_types.hpp"
@ -80,7 +80,7 @@ TEST(QueryPlan, CreateNodeWithAttributes) {
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
TEST(QueryPlan, FineGrainedCreateNodeWithAttributes) { TEST(QueryPlan, FineGrainedCreateNodeWithAttributes) {
memgraph::utils::license::global_license_checker.EnableTesting(); memgraph::license::global_license_checker.EnableTesting();
memgraph::query::AstStorage ast; memgraph::query::AstStorage ast;
memgraph::query::SymbolTable symbol_table; memgraph::query::SymbolTable symbol_table;
memgraph::storage::Storage db; memgraph::storage::Storage db;
@ -164,7 +164,7 @@ TEST(QueryPlan, CreateReturn) {
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
TEST(QueryPlan, FineGrainedCreateReturn) { 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 // test CREATE (n:Person {age: 42}) RETURN n, n.age
memgraph::storage::Storage db; memgraph::storage::Storage db;
@ -310,7 +310,7 @@ class CreateExpandWithAuthFixture : public testing::Test {
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; 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) { void ExecuteCreateExpand(bool cycle, memgraph::auth::User &user) {
const auto label_node_1 = dba.NameToLabel("Node1"); const auto label_node_1 = dba.NameToLabel("Node1");
@ -470,7 +470,7 @@ class MatchCreateNodeWithAuthFixture : public testing::Test {
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
void InitGraph() { void InitGraph() {
// add three nodes we'll match and expand-create from // add three nodes we'll match and expand-create from
@ -600,7 +600,7 @@ class MatchCreateExpandWithAuthFixture : public testing::Test {
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
void InitGraph() { void InitGraph() {
// add three nodes we'll match and expand-create from // add three nodes we'll match and expand-create from
@ -818,7 +818,7 @@ class DeleteOperatorWithAuthFixture : public testing::Test {
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
void InitGraph() { void InitGraph() {
std::vector<memgraph::query::VertexAccessor> vertices; std::vector<memgraph::query::VertexAccessor> vertices;
@ -1253,7 +1253,7 @@ TEST(QueryPlan, SetLabels) {
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
TEST(QueryPlan, SetLabelsWithFineGrained) { 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, auto set_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba,
std::vector<memgraph::storage::LabelId> labels) { std::vector<memgraph::storage::LabelId> labels) {
ASSERT_TRUE(dba.InsertVertex().AddLabel(labels[0]).HasValue()); ASSERT_TRUE(dba.InsertVertex().AddLabel(labels[0]).HasValue());
@ -1426,7 +1426,7 @@ TEST(QueryPlan, RemoveLabels) {
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
TEST(QueryPlan, RemoveLabelsFineGrainedFiltering) { 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, auto remove_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba,
std::vector<memgraph::storage::LabelId> labels) { std::vector<memgraph::storage::LabelId> labels) {
auto v1 = dba.InsertVertex(); 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::PropertyId edge_prop{dba.NameToProperty(edge_prop_name)};
const memgraph::storage::PropertyValue edge_prop_value{1}; 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) { void SetVertexProperty(memgraph::query::VertexAccessor vertex) {
static_cast<void>(vertex.SetProperty(entity_prop, entity_prop_value)); static_cast<void>(vertex.SetProperty(entity_prop, entity_prop_value));

View File

@ -30,10 +30,10 @@
#include "auth/auth.hpp" #include "auth/auth.hpp"
#include "auth/models.hpp" #include "auth/models.hpp"
#include "glue/auth_checker.hpp" #include "glue/auth_checker.hpp"
#include "license/license.hpp"
#include "query/context.hpp" #include "query/context.hpp"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "query/plan/operator.hpp" #include "query/plan/operator.hpp"
#include "utils/license.hpp"
#include "utils/synchronized.hpp" #include "utils/synchronized.hpp"
using namespace memgraph::query; using namespace memgraph::query;
@ -50,7 +50,7 @@ class MatchReturnFixture : public testing::Test {
void AddVertices(int count) { void AddVertices(int count) {
for (int i = 0; i < count; i++) dba.InsertVertex(); 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> PathResults(std::shared_ptr<Produce> &op) {
std::vector<Path> res; std::vector<Path> res;
@ -485,7 +485,7 @@ class ExpandFixture : public testing::Test {
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue()); ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue()); ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue()); ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
memgraph::utils::license::global_license_checker.EnableTesting(); memgraph::license::global_license_checker.EnableTesting();
dba.AdvanceCommand(); dba.AdvanceCommand();
} }
@ -628,7 +628,7 @@ class QueryPlanExpandVariable : public testing::Test {
std::nullopt_t nullopt = std::nullopt; std::nullopt_t nullopt = std::nullopt;
void SetUp() { void SetUp() {
memgraph::utils::license::global_license_checker.EnableTesting(); memgraph::license::global_license_checker.EnableTesting();
// create the graph // create the graph
int chain_length = 3; int chain_length = 3;
@ -1778,7 +1778,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
Symbol total_weight = symbol_table.CreateSymbol("total_weight", true); Symbol total_weight = symbol_table.CreateSymbol("total_weight", true);
void SetUp() { void SetUp() {
memgraph::utils::license::global_license_checker.EnableTesting(); memgraph::license::global_license_checker.EnableTesting();
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
v.push_back(dba.InsertVertex()); v.push_back(dba.InsertVertex());
@ -2208,7 +2208,7 @@ class QueryPlanExpandAllShortestPaths : public testing::Test {
Symbol total_weight = symbol_table.CreateSymbol("total_weight", true); Symbol total_weight = symbol_table.CreateSymbol("total_weight", true);
void SetUp() { void SetUp() {
memgraph::utils::license::global_license_checker.EnableTesting(); memgraph::license::global_license_checker.EnableTesting();
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
v.push_back(dba.InsertVertex()); v.push_back(dba.InsertVertex());

View File

@ -13,11 +13,11 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <unordered_map> #include <unordered_map>
#include "license/license.hpp"
#include "query/frontend/ast/ast.hpp" #include "query/frontend/ast/ast.hpp"
#include "query/frontend/ast/ast_visitor.hpp" #include "query/frontend/ast/ast_visitor.hpp"
#include "query/frontend/semantic/required_privileges.hpp" #include "query/frontend/semantic/required_privileges.hpp"
#include "storage/v2/id_types.hpp" #include "storage/v2/id_types.hpp"
#include "utils/license.hpp"
#include "query_common.hpp" #include "query_common.hpp"
@ -100,7 +100,7 @@ TEST_F(TestPrivilegeExtractor, CreateIndex) {
} }
#ifdef MG_ENTERPRISE #ifdef MG_ENTERPRISE
TEST_F(TestPrivilegeExtractor, AuthQuery) { 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 label_privileges = std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{};
auto edge_type_privileges = auto edge_type_privileges =
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{}; std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{};