Skip to content

Commit

Permalink
add jwt cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendon committed Nov 16, 2024
1 parent 24581ea commit 7cc6bcb
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 18 deletions.
20 changes: 19 additions & 1 deletion .github/workflows/cmake-single-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ jobs:
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y libmongoc-1.0-0 curl cmake build-essential
sudo apt-get install -y libmongoc-1.0-0 curl cmake build-essential \
libssl-dev libboost-all-dev
- name: Setup External Libraries
run: |
Expand Down Expand Up @@ -52,6 +53,23 @@ jobs:
cd ../..
rm mongo-cxx-driver.tar.gz
# Install jwt-cpp
git clone https://github.com/Thalhammer/jwt-cpp.git
cd jwt-cpp
mkdir build && cd build
cmake ..
sudo make install
cd ../..
# Install bcrypt
git clone https://github.com/trusch/libbcrypt.git bcrypt
cd bcrypt
mkdir build && cd build
cmake ..
make
sudo make install
cd ../..
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}

Expand Down
37 changes: 20 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ set(ASIO_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/external_libraries/asio/include)
if (APPLE)
set(MONGOCXX_LIB_PATH "/usr/local/lib/libmongocxx.dylib")
set(BSONCXX_LIB_PATH "/usr/local/lib/libbsoncxx.dylib")
set(BCRYPT_INCLUDE_DIR "/usr/local/include")
set(BCRYPT_LIBRARY "/usr/local/lib/libbcrypt.a")
else()
set(MONGOCXX_LIB_PATH "/usr/local/lib/libmongocxx.so")
set(BSONCXX_LIB_PATH "/usr/local/lib/libbsoncxx.so")
Expand All @@ -29,29 +31,14 @@ set(INCLUDE_PATHS
/usr/local/include/bsoncxx/v_noabi
/usr/local/include/libmongoc-1.0
/usr/local/include/libbson-1.0
/usr/local/include/bcrypt
/usr/local/include/bsoncxx/v_noabi/bsoncxx/third_party/mnmlstc
include
)

# Add these lines to find MongoDB C++ driver
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${MONGO_CXX_ROOT}/build)


# Include directories
set(INCLUDE_PATHS
${BOOST_ROOT}
${CROW_INCLUDE_DIR}
${ASIO_INCLUDE_DIR}
/usr/local/include/bsoncxx/v_noabi/bsoncxx/third_party/mnmlstc
include
)

include_directories ("/usr/local/include/mongocxx/v_noabi")
include_directories("/usr/local/include/libmongoc-1.0")
include_directories("/usr/local/include/bsoncxx/v_noabi")
include_directories("/usr/local/include/libbson-1.0")
include_directories("/usr/local/lib -lmongocxx -lbsoncxx")


set(SOURCE_FILES
src/main.cpp
src/RouteController.cpp
Expand All @@ -61,6 +48,7 @@ set(SOURCE_FILES
src/services/Healthcare.cpp
src/services/Outreach.cpp
src/services/Shelter.cpp
src/Auth.cpp
)

set(TEST_FILES
Expand All @@ -70,6 +58,7 @@ set(TEST_FILES
test/OutreachUnitTests.cpp
test/ShelterUnitTests.cpp
test/RouteControllerUnitTests.cpp
#test/AuthUnitTests.cpp
)

set(SOURCE_FILES_NO_MAIN
Expand All @@ -80,11 +69,21 @@ set(SOURCE_FILES_NO_MAIN
src/services/Healthcare.cpp
src/services/Outreach.cpp
src/services/Shelter.cpp
src/Auth.cpp
)

# Add bcrypt to your include paths
list(APPEND INCLUDE_PATHS ${BCRYPT_INCLUDE_DIR})

# Main project executable
add_executable(GitGud ${SOURCE_FILES})

# find_package(BCrypt REQUIRED)
# target_link_libraries(GitGud PRIVATE BCrypt)

find_package(jwt-cpp CONFIG REQUIRED)
target_link_libraries(GitGud PRIVATE jwt-cpp::jwt-cpp)

if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(GitGud PRIVATE -Wno-deprecated-declarations)
endif()
Expand All @@ -103,12 +102,14 @@ target_include_directories(GitGud PUBLIC ${INCLUDE_PATHS})

# Link libraries
target_link_libraries(GitGud PRIVATE
${BCRYPT_LIBRARY}
gtest
gtest_main
gmock
gmock_main
${MONGOCXX_LIB_PATH}
${BSONCXX_LIB_PATH}
jwt-cpp::jwt-cpp
)

enable_testing()
Expand All @@ -123,12 +124,14 @@ endif()
target_include_directories(GitGudTests PRIVATE ${INCLUDE_PATHS})

target_link_libraries(GitGudTests PRIVATE
${BCRYPT_LIBRARY}
gtest
gtest_main
gmock
gmock_main
${MONGOCXX_LIB_PATH}
${BSONCXX_LIB_PATH}
jwt-cpp::jwt-cpp
)

include(GoogleTest)
Expand Down
1 change: 1 addition & 0 deletions bcrypt
Submodule bcrypt added at d6523c
135 changes: 135 additions & 0 deletions include/Auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#ifndef AUTH_H
#define AUTH_H

#include <string>
#include <memory>
#include <stdexcept>
#include <optional>
#include "DatabaseManager.h"
#include "../external_libraries/Crow/include/crow.h"

// Custom exceptions for authentication
class AuthException : public std::runtime_error {
public:
explicit AuthException(const std::string& message) : std::runtime_error(message) {}
};

class InvalidCredentialsException : public AuthException {
public:
InvalidCredentialsException() : AuthException("Invalid email or password") {}
};

class UserAlreadyExistsException : public AuthException {
public:
UserAlreadyExistsException() : AuthException("User with this email already exists") {}
};

// User model
struct User {
std::string id;
std::string username;
std::string email;
std::string passwordHash;
std::string role;
std::string createdAt;

// Constructor for creating a new user
User(const std::string& username,
const std::string& email,
const std::string& passwordHash,
const std::string& role = "user")
: username(username)
, email(email)
, passwordHash(passwordHash)
, role(role) {}

// Default constructor
User() = default;
};

// JWT payload structure
struct JWTPayload {
std::string userId;
std::string email;
std::string role;
int64_t exp; // Expiration time
};

class AuthService {
private:
// Private constructor for singleton pattern
AuthService();

// Delete copy constructor and assignment operator
AuthService(const AuthService&) = delete;
AuthService& operator=(const AuthService&) = delete;

public:
// Static method to get the singleton instance
static AuthService& getInstance() {
static AuthService instance;
return instance;
}

explicit AuthService(DatabaseManager& dbManager);
~AuthService() = default;

// User registration and login
std::string registerUser(const std::string& username,
const std::string& email,
const std::string& password);

std::string loginUser(const std::string& email,
const std::string& password);

// JWT operations
std::string generateJWT(const User& user);
bool verifyJWT(const std::string& token);
std::optional<JWTPayload> decodeJWT(const std::string& token);

// User operations
std::optional<User> findUserByEmail(const std::string& email);
bool updateUserPassword(const std::string& userId, const std::string& newPassword);
bool deleteUser(const std::string& userId);

// Role-based authorization
bool hasRole(const std::string& token, const std::string& requiredRole);

private:
DatabaseManager& dbManager;
const std::string collection_name = "users";
const int JWT_EXPIRATION_HOURS = 24;
const std::string JWT_SECRET = "your-secret-key"; // In production, load from env variables

// Password hashing
std::string hashPassword(const std::string& password);
bool verifyPassword(const std::string& password, const std::string& hash);

// JWT utilities
int64_t getCurrentTimestamp();
int64_t getExpirationTimestamp();

// User validation
bool isValidEmail(const std::string& email);
bool isValidPassword(const std::string& password);
bool isValidUsername(const std::string& username);

// Database operations
std::vector<std::pair<std::string, std::string>> createUserDocument(
const std::string& username,
const std::string& email,
const std::string& passwordHash,
const std::string& role = "user"
);
};

// Middleware function for token verification
bool authenticateToken(const crow::request& req);

// Middleware function for role-based authorization
bool authorizeRole(const crow::request& req, const std::string& requiredRole);

// Helper function to extract token from Authorization header
std::string extractToken(const std::string& authHeader);

#endif // AUTH_H
5 changes: 5 additions & 0 deletions include/DatabaseManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ class DatabaseManager {
virtual bsoncxx::document::value getResources(
const std::string& resourceType);

static DatabaseManager& getInstance() {
static DatabaseManager instance("mongodb://localhost:27017");
return instance;
}

protected:
std::optional<mongocxx::client> conn;

Expand Down
1 change: 1 addition & 0 deletions jwt-cpp
Submodule jwt-cpp added at 6dd190
27 changes: 27 additions & 0 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,33 @@ else
echo "MongoDB C++ Driver already exists, skipping installation."
fi

# Download and install jwt-cpp
if [ ! -d "jwt-cpp" ]; then
echo "Installing jwt-cpp..."
git clone https://github.com/Thalhammer/jwt-cpp.git
cd jwt-cpp
mkdir build && cd build
cmake ..
sudo make install
cd ../..
else
echo "jwt-cpp already exists, skipping installation."
fi

# Download and install bcrypt
if [ ! -d "bcrypt" ]; then
echo "Installing bcrypt..."
git clone https://github.com/trusch/libbcrypt.git bcrypt
cd bcrypt
mkdir build && cd build
cmake ..
make
sudo make install
cd ../..
else
echo "bcrypt already exists, skipping installation."
fi

echo "All external libraries processed successfully."

# Return to external libraries directory
Expand Down
Loading

0 comments on commit 7cc6bcb

Please sign in to comment.