More refactoring. Implement an ACL file. Care about token timeouts.
This commit is contained in:
parent
deb1cef30f
commit
4f60efa87a
|
|
@ -4,6 +4,7 @@ project(j7s-mosquitto-plugin)
|
||||||
include(external-deps.cmake)
|
include(external-deps.cmake)
|
||||||
|
|
||||||
find_package(OpenSSL)
|
find_package(OpenSSL)
|
||||||
|
find_package(yaml-cpp)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
|
@ -14,12 +15,19 @@ target_include_directories(utils PUBLIC
|
||||||
)
|
)
|
||||||
target_link_libraries(utils OpenSSL::Crypto jwt-cpp)
|
target_link_libraries(utils OpenSSL::Crypto jwt-cpp)
|
||||||
|
|
||||||
add_library(j7s-plugin SHARED src/j7s-plugin.cpp src/AuthList.cpp src/Authorizer.cpp)
|
add_library(Authorizer SHARED src/Authorizer.cpp src/AuthList.cpp)
|
||||||
|
target_include_directories(Authorizer PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
)
|
||||||
|
target_link_libraries(Authorizer utils yaml-cpp)
|
||||||
|
|
||||||
|
add_library(j7s-plugin SHARED src/j7s-plugin.cpp)
|
||||||
target_include_directories(j7s-plugin PUBLIC
|
target_include_directories(j7s-plugin PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
target_link_libraries(j7s-plugin utils)
|
target_link_libraries(j7s-plugin utils Authorizer)
|
||||||
|
|
||||||
add_executable(gen-token src/gen-token.cpp)
|
add_executable(gen-token src/gen-token.cpp)
|
||||||
target_include_directories(gen-token PUBLIC
|
target_include_directories(gen-token PUBLIC
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Authentication using JWTs for the mosquitto mqtt broker.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
```
|
```
|
||||||
sudo apt install mosquitto-dev g++ cmake libmosquitto-dev mosquitto-clients openssl libssl-dev googletest
|
sudo apt install mosquitto-dev g++ cmake libmosquitto-dev mosquitto-clients openssl libssl-dev libyaml-cpp-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generating offline keys
|
## Generating offline keys
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
default:
|
||||||
|
can_read: true
|
||||||
|
can_write: false
|
||||||
|
jimmy:
|
||||||
|
can_read: true
|
||||||
|
can_write: true
|
||||||
|
|
@ -6,12 +6,14 @@ protocol websockets
|
||||||
allow_anonymous false
|
allow_anonymous false
|
||||||
auth_plugin /home/jimmy/Develop/mosquitto-plugin/build/libj7s-plugin.so
|
auth_plugin /home/jimmy/Develop/mosquitto-plugin/build/libj7s-plugin.so
|
||||||
auth_opt_issuer https://auth.jpace121.net/realms/jpace121-main
|
auth_opt_issuer https://auth.jpace121.net/realms/jpace121-main
|
||||||
auth_opt_public_key /home/jimmy/Develop/mosquitto-plugin/test/key.pem
|
auth_opt_public_key /home/jimmy/Develop/mosquitto-plugin/examples/key.pem
|
||||||
|
auth_opt_acl_file /home/jimmy/Develop/mosquitto-plugin/examples/acl.yaml
|
||||||
|
|
||||||
listener 8081
|
listener 8081
|
||||||
protocol mqtt
|
protocol mqtt
|
||||||
allow_anonymous false
|
allow_anonymous false
|
||||||
auth_plugin /home/jimmy/Develop/mosquitto-plugin/build/libj7s-plugin.so
|
auth_plugin /home/jimmy/Develop/mosquitto-plugin/build/libj7s-plugin.so
|
||||||
auth_opt_issuer https://auth.jpace121.net/realms/jpace121-main
|
auth_opt_issuer https://auth.jpace121.net/realms/jpace121-main
|
||||||
auth_opt_public_key /home/jimmy/Develop/mosquitto-plugin/test/key.pem
|
auth_opt_public_key /home/jimmy/Develop/mosquitto-plugin/examples/key.pem
|
||||||
|
auth_opt_acl_file /home/jimmy/Develop/mosquitto-plugin/examples/acl.yaml
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,19 +12,22 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <forward_list>
|
#include <chrono>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
using time_T = std::chrono::time_point<std::chrono::system_clock>;
|
||||||
|
|
||||||
// A list with easily checkable contents.
|
// A list with easily checkable contents.
|
||||||
class AuthList
|
class AuthList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AuthList();
|
AuthList();
|
||||||
|
|
||||||
void add(const std::string& username);
|
void add(const std::string& username, const time_T& expr_time);
|
||||||
void remove(const std::string& username);
|
void remove(const std::string& username);
|
||||||
bool confirm(const std::string& username);
|
bool confirm(const std::string& username);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::forward_list<std::string> _allowedUsernames;
|
std::map<std::string, time_T> _map;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include <j7s-plugin/AuthList.hpp>
|
#include <j7s-plugin/AuthList.hpp>
|
||||||
|
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
@ -22,7 +24,7 @@
|
||||||
class Authorizer
|
class Authorizer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Authorizer(const std::string& pub_key, const std::string& issuer);
|
Authorizer(const std::string& pub_key, const std::string& issuer, const std::string& aclFilePath);
|
||||||
static std::optional<std::string> read_key(const std::string& key_file);
|
static std::optional<std::string> read_key(const std::string& key_file);
|
||||||
void add_unknown(const std::string& username);
|
void add_unknown(const std::string& username);
|
||||||
bool is_unknown(const std::string& username);
|
bool is_unknown(const std::string& username);
|
||||||
|
|
@ -35,6 +37,8 @@ private:
|
||||||
AuthList _readList;
|
AuthList _readList;
|
||||||
AuthList _unknownList;
|
AuthList _unknownList;
|
||||||
|
|
||||||
|
YAML::Node _aclFile;
|
||||||
|
|
||||||
std::string _pub_key;
|
std::string _pub_key;
|
||||||
std::string _issuer;
|
std::string _issuer;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
std::optional<std::string> read_key(const std::string & key_file);
|
std::optional<std::string> read_key(const std::string & key_file);
|
||||||
|
|
||||||
bool validate(
|
std::tuple<bool, std::chrono::time_point<std::chrono::system_clock>> validate(
|
||||||
const std::string & token,
|
const std::string & token,
|
||||||
const std::string & username,
|
const std::string & username,
|
||||||
const std::string & issuer,
|
const std::string & issuer,
|
||||||
|
|
|
||||||
|
|
@ -14,36 +14,38 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <j7s-plugin/AuthList.hpp>
|
#include <j7s-plugin/AuthList.hpp>
|
||||||
|
|
||||||
AuthList::AuthList() : _allowedUsernames{} {}
|
AuthList::AuthList() : _map{} {}
|
||||||
|
|
||||||
void AuthList::add(const std::string & username)
|
void AuthList::add(const std::string & username, const time_T& expr_time)
|
||||||
{
|
{
|
||||||
// Is the username already in the list?
|
// Add the user to the list or update it's expr time if
|
||||||
// If not add it.
|
// it's already there.
|
||||||
if (not confirm(username))
|
_map[username] = expr_time;
|
||||||
{
|
|
||||||
_allowedUsernames.emplace_front(username);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthList::remove(const std::string & username)
|
void AuthList::remove(const std::string & username)
|
||||||
{
|
{
|
||||||
// Is the user in the list?
|
// Remove the user
|
||||||
// Is so, remove it,
|
_map.erase(username);
|
||||||
if (confirm(username))
|
|
||||||
{
|
|
||||||
_allowedUsernames.remove(username);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthList::confirm(const std::string & username)
|
bool AuthList::confirm(const std::string & username)
|
||||||
{
|
{
|
||||||
// Is the user in the list?
|
// Is the user in the map?
|
||||||
const auto found =
|
const auto iter = _map.find(username);
|
||||||
std::find(std::begin(_allowedUsernames), std::end(_allowedUsernames), username);
|
|
||||||
if (found != std::end(_allowedUsernames))
|
if(iter == _map.end())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has the token expired?
|
||||||
|
const auto now = std::chrono::system_clock::now();
|
||||||
|
const auto expr_time = std::get<1>(*iter);
|
||||||
|
if(now < expr_time)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,21 @@
|
||||||
#include <j7s-plugin/AuthList.hpp>
|
#include <j7s-plugin/AuthList.hpp>
|
||||||
#include <j7s-plugin/Authorizer.hpp>
|
#include <j7s-plugin/Authorizer.hpp>
|
||||||
|
|
||||||
Authorizer::Authorizer(const std::string & pub_key, const std::string & issuer) :
|
#include <tuple>
|
||||||
_pub_key{pub_key}, _issuer{issuer}
|
|
||||||
|
// Util.
|
||||||
|
std::tuple<bool, bool> checkACL(const YAML::Node& user);
|
||||||
|
|
||||||
|
// Class implementation.
|
||||||
|
Authorizer::Authorizer(
|
||||||
|
const std::string & pub_key, const std::string & issuer, const std::string & aclFilePath) :
|
||||||
|
_pub_key{pub_key}, _issuer{issuer}, _aclFile{aclFilePath}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Authorizer::add_unknown(const std::string & username)
|
void Authorizer::add_unknown(const std::string & username)
|
||||||
{
|
{
|
||||||
_unknownList.add(username);
|
_unknownList.add(username, time_T::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Authorizer::is_unknown(const std::string & username)
|
bool Authorizer::is_unknown(const std::string & username)
|
||||||
|
|
@ -34,20 +41,35 @@ bool Authorizer::is_unknown(const std::string & username)
|
||||||
|
|
||||||
bool Authorizer::add(const std::string & token, const std::string & username)
|
bool Authorizer::add(const std::string & token, const std::string & username)
|
||||||
{
|
{
|
||||||
const auto validated = validate(token, username, _issuer, _pub_key);
|
const auto [validated, expr_time] = validate(token, username, _issuer, _pub_key);
|
||||||
if (not validated)
|
if (not validated)
|
||||||
{
|
{
|
||||||
std::cerr << "Not validated." << std::endl;
|
std::cerr << "Not validated." << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check ACL file to see which one.
|
// Check the ACL file.
|
||||||
_writeList.add(username);
|
// TODO: Make sure default is in ACL file.
|
||||||
_readList.add(username);
|
if (not _aclFile[username])
|
||||||
|
{
|
||||||
|
const auto checkACL(_aclFile["default"]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto [can_read, can_write] = checkACL(_aclFile[username]);
|
||||||
|
|
||||||
|
if (can_read)
|
||||||
|
{
|
||||||
|
_readList.add(username, expr_time);
|
||||||
|
}
|
||||||
|
if (can_write)
|
||||||
|
{
|
||||||
|
_writeList.add(username, expr_time);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Authorizer::can_read(const std::string & username)
|
bool Authorizer::can_read(const std::string & username)
|
||||||
{
|
{
|
||||||
return _readList.confirm(username);
|
return _readList.confirm(username);
|
||||||
|
|
@ -64,3 +86,20 @@ void Authorizer::logout(const std::string & username)
|
||||||
_readList.remove(username);
|
_readList.remove(username);
|
||||||
_unknownList.remove(username);
|
_unknownList.remove(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Util.
|
||||||
|
std::tuple<bool, bool> checkACL(const YAML::Node& user)
|
||||||
|
{
|
||||||
|
bool can_read = false;
|
||||||
|
bool can_write = false;
|
||||||
|
if(user["can_read"] and user["can_read"].as<bool>())
|
||||||
|
{
|
||||||
|
can_read = true;
|
||||||
|
}
|
||||||
|
if(user["can_write"] and user["can_write"].as<bool>())
|
||||||
|
{
|
||||||
|
can_write = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple(can_read, can_write);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,12 @@
|
||||||
#include <j7s-plugin/j7s-plugin.h>
|
#include <j7s-plugin/j7s-plugin.h>
|
||||||
|
|
||||||
#include <j7s-plugin/Authorizer.hpp>
|
#include <j7s-plugin/Authorizer.hpp>
|
||||||
|
|
||||||
|
#include <j7s-plugin/utils.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
// Mosquitto Globals
|
// Mosquitto Globals
|
||||||
static mosquitto_plugin_id_t * plugin_id = nullptr;
|
static mosquitto_plugin_id_t * plugin_id = nullptr;
|
||||||
|
|
@ -41,7 +45,7 @@ int mosquitto_plugin_init(
|
||||||
{
|
{
|
||||||
plugin_id = identifier;
|
plugin_id = identifier;
|
||||||
|
|
||||||
if (option_count != 2)
|
if (option_count < 3)
|
||||||
{
|
{
|
||||||
mosquitto_log_printf(MOSQ_LOG_ERR, "Missing an option. Found: %d", option_count);
|
mosquitto_log_printf(MOSQ_LOG_ERR, "Missing an option. Found: %d", option_count);
|
||||||
return MOSQ_ERR_INVAL;
|
return MOSQ_ERR_INVAL;
|
||||||
|
|
@ -49,12 +53,13 @@ int mosquitto_plugin_init(
|
||||||
|
|
||||||
std::string public_key;
|
std::string public_key;
|
||||||
std::string issuer;
|
std::string issuer;
|
||||||
|
std::filesystem::path aclFilePath;
|
||||||
for (int index = 0; index < option_count; index++)
|
for (int index = 0; index < option_count; index++)
|
||||||
{
|
{
|
||||||
const auto key = std::string(options[index].key);
|
const auto key = std::string(options[index].key);
|
||||||
if (key == "public_key")
|
if (key == "public_key")
|
||||||
{
|
{
|
||||||
const auto key = Authorizer::read_key(std::string(options[index].value));
|
const auto key = read_key(std::string(options[index].value));
|
||||||
if (not key or key->empty())
|
if (not key or key->empty())
|
||||||
{
|
{
|
||||||
mosquitto_log_printf(MOSQ_LOG_ERR, "Could not read public key.");
|
mosquitto_log_printf(MOSQ_LOG_ERR, "Could not read public key.");
|
||||||
|
|
@ -71,9 +76,20 @@ int mosquitto_plugin_init(
|
||||||
return MOSQ_ERR_INVAL;
|
return MOSQ_ERR_INVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (key == "acl_file")
|
||||||
|
{
|
||||||
|
std::string acl_file_string = std::string(options[index].value);
|
||||||
|
if (acl_file_string.empty())
|
||||||
|
{
|
||||||
|
mosquitto_log_printf(MOSQ_LOG_ERR, "acl_file not set.");
|
||||||
|
return MOSQ_ERR_INVAL;
|
||||||
|
}
|
||||||
|
aclFilePath = std::filesystem::path(acl_file_string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
authorizer = std::make_unique<Authorizer>(public_key, issuer);
|
authorizer = std::make_unique<Authorizer>(
|
||||||
|
public_key, issuer, std::filesystem::absolute(aclFilePath).string());
|
||||||
|
|
||||||
// Register the callbacks.
|
// Register the callbacks.
|
||||||
mosquitto_callback_register(
|
mosquitto_callback_register(
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ std::optional<std::string> read_key(const std::string & key_file)
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validate(
|
std::tuple<bool, std::chrono::time_point<std::chrono::system_clock>> validate(
|
||||||
const std::string & token,
|
const std::string & token,
|
||||||
const std::string & username,
|
const std::string & username,
|
||||||
const std::string & issuer,
|
const std::string & issuer,
|
||||||
|
|
@ -50,7 +50,7 @@ bool validate(
|
||||||
catch (jwt::error::token_verification_exception & exception)
|
catch (jwt::error::token_verification_exception & exception)
|
||||||
{
|
{
|
||||||
std::cerr << exception.what() << std::endl;
|
std::cerr << exception.what() << std::endl;
|
||||||
return false;
|
return std::make_tuple(false, std::chrono::system_clock::now());
|
||||||
}
|
}
|
||||||
auto claims = decoded_token.get_payload_claims();
|
auto claims = decoded_token.get_payload_claims();
|
||||||
|
|
||||||
|
|
@ -58,22 +58,34 @@ bool validate(
|
||||||
if (not claims.contains("upn"))
|
if (not claims.contains("upn"))
|
||||||
{
|
{
|
||||||
std::cerr << "Missing upn." << std::endl;
|
std::cerr << "Missing upn." << std::endl;
|
||||||
return false;
|
return std::make_tuple(false, std::chrono::system_clock::now());
|
||||||
}
|
}
|
||||||
if (claims["upn"].as_string() != username)
|
if (claims["upn"].as_string() != username)
|
||||||
{
|
{
|
||||||
std::cerr << "Wrong username." << std::endl;
|
std::cerr << "Wrong username." << std::endl;
|
||||||
return false;
|
return std::make_tuple(false, std::chrono::system_clock::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for mqtt-write claim value.
|
// Check for mqtt-write claim value.
|
||||||
if (not claims.contains("mqtt"))
|
if (not claims.contains("mqtt"))
|
||||||
{
|
{
|
||||||
std::cerr << "Missing mqtt claim." << std::endl;
|
std::cerr << "Missing mqtt claim." << std::endl;
|
||||||
return false;
|
return std::make_tuple(false, std::chrono::system_clock::now());
|
||||||
|
}
|
||||||
|
if(not claims["mqtt"].as_bool())
|
||||||
|
{
|
||||||
|
std::cerr << "Not claiming can do mqtt." << std::endl;
|
||||||
|
return std::make_tuple(false, std::chrono::system_clock::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
return claims["mqtt"].as_bool();
|
// Do we have an expiration time?
|
||||||
|
if(not claims.contains("exp"))
|
||||||
|
{
|
||||||
|
std::cerr << "Missing expiration time claim." << std::endl;
|
||||||
|
return std::make_tuple(false, std::chrono::system_clock::now());
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple(true, claims["exp"].as_date());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string gen_token(
|
std::string gen_token(
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,104 @@
|
||||||
#include <j7s-plugin/Authorizer.hpp>
|
// Copyright 2022 James Pace
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#include <j7s-plugin/utils.h>
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
constexpr std::string priv_key_a =
|
||||||
|
R"(-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+ouwDpYOWDEyM
|
||||||
|
nJhwejOn+boDxw4ntiOR3kRzIANuJrbEPf3UJFL+SPPzzY7NU1A6XPz/NAccbvfn
|
||||||
|
c78dj12rsV6st5GuFx9QbxYn2XQb8vnxj+DhvSrNk+qy7IMaN/3NGrAoWemSIRIW
|
||||||
|
VB7xbVybQyvAucgaTDKnU72viNOxqg8v5bGF+WtTjKwezmYtyQ8Z7dpGQbML1tkT
|
||||||
|
EQwTq5nnLre8F/t6fTS4ziGVw7STggSroAHazphzYmqc3W68jY/SQefOilALwzFp
|
||||||
|
/Cxoubj0d+f3OYT5jnfMPSpKJiYNlLqxCJPGjNcSRxjzzRt/cRYzhAPfriO/fkYG
|
||||||
|
tQcLNB5dAgMBAAECggEAd+qyPeT6rgNUj8rdlTs5jTtoiIHJZK+NFm/TbPvBTKPr
|
||||||
|
qew45B5pWm13j3BJmN0EhYIC32HR60/ef2hu2uBZEuyC2nCqofEHkKggLrb5867X
|
||||||
|
DN3tnvJIn4KhSyW9nluEOmXEU82jQHmvD/6gbEvXyg7p0dTLi8dMwbbKhkWyrHlu
|
||||||
|
lqvuJUvdDFv9X2k/y440cKhyssP5HlR/sXn+za5XQoPEtZIh9xM9sg0slSIq+eu1
|
||||||
|
FRKS0Geo8e93L31jXn1GoNTSCIupyj3EZiKGE0xhxTmjoO+dEEVg6gTdYNAQd6Nx
|
||||||
|
aaMdLRNo2hfk7ATA+L3hcfFSM+3QPg7wFCInGHQF/QKBgQD1aQ+GX6vl3lmZs+TX
|
||||||
|
6Hp7qtL6g+TJ2/fSXqbMURHBtdTFFzROqtzIAHwp30fGCGG9reAmRZVHv2mF7U49
|
||||||
|
3qk9/TcK4nUsGq/o87RKjmrUmLrEx1mtJK10BuJW2lEPIBG6Ws9tGAwSzhs5Lw5H
|
||||||
|
LnbQHD4dftjhqhNX8ZoU5oG7dwKBgQDG3MwqaMQ55sh8+ci6tZ4pOm1/8Lin0gyh
|
||||||
|
iNFa8UxFkTsaLHnDXrsUJCkqRwtNtV4Fhbv7x+4smGxDzuJkF6U7uxONJgWp1qlW
|
||||||
|
6B0SBgKUPdxeGJYG4+ww9qsapARZzZ/1GLYv47+kPs0slz+A0OHeNs1BKhGJLK23
|
||||||
|
P88MSG8BywKBgFnLs26Lmy5lCYwAEwAdhJOzkbcwg4qI/kjvcUDZeRHUIqJrNyyB
|
||||||
|
wH8+DjCUDoMblgf9k0Ltuw2hsE7c4gApdOvFt1o4On+E1FD8uz98lQJtUAmol9uO
|
||||||
|
zBjkW/VDtN0/8rypdbSJVAGdgMCPwz2wdrD3ZJMOUvVfcex/7s0u+tFJAoGAJoPb
|
||||||
|
ExepcaFuES57nxXP5SJI1O+1g+NdyOdrzNZRNGQVc1NL3ff5+cOrKWILIWjQJfep
|
||||||
|
2fD2AzMePN/T3xjpSrFH7x1/GU7XC1r3TmdVloqIpLzUSc9ZDn6n0wgTQ6Vcpqa7
|
||||||
|
mnjcxB3ZtRoyFWvfYx9wD3/rV4sMtiIoorNgtJMCgYABDGH571InLE9HMO1+Czmp
|
||||||
|
zyvcbTAq8GiN0G4Rok95+THfa726N6BcmkZUK1xWaleO6xNGrDsBghfmgw629Ujk
|
||||||
|
UJ73ERYyATbA4GHM9f3dbje8pd2SFa4xF+0Xp09qY380aJrZSWsklBZPUmYiU6+W
|
||||||
|
i2MlHfF+44rBO9igkUjQKA==
|
||||||
|
-----END PRIVATE KEY-----)"
|
||||||
|
|
||||||
|
constexpr std::string pub_key_a =
|
||||||
|
R"(-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvqLsA6WDlgxMjJyYcHoz
|
||||||
|
p/m6A8cOJ7Yjkd5EcyADbia2xD391CRS/kjz882OzVNQOlz8/zQHHG7353O/HY9d
|
||||||
|
q7FerLeRrhcfUG8WJ9l0G/L58Y/g4b0qzZPqsuyDGjf9zRqwKFnpkiESFlQe8W1c
|
||||||
|
m0MrwLnIGkwyp1O9r4jTsaoPL+WxhflrU4ysHs5mLckPGe3aRkGzC9bZExEME6uZ
|
||||||
|
5y63vBf7en00uM4hlcO0k4IEq6AB2s6Yc2JqnN1uvI2P0kHnzopQC8MxafwsaLm4
|
||||||
|
9Hfn9zmE+Y53zD0qSiYmDZS6sQiTxozXEkcY880bf3EWM4QD364jv35GBrUHCzQe
|
||||||
|
XQIDAQAB
|
||||||
|
-----END PUBLIC KEY-----)";
|
||||||
|
constexpr std::string priv_key_b =
|
||||||
|
R"(-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCYq8QNOXZRoAid
|
||||||
|
R7cKE9byr+9WekPMNDNkaKTjRUoXj8lUgno3y5tIDEIqhcv4thTLAxzQD4N+bVA3
|
||||||
|
XF1ZMfm2GmM0O61AtpKwL6diBeGpCTunwzl9nrTeackQmwqRwllc3kW/npudNn12
|
||||||
|
M9m4wsgLK98juyY6pZAeTlAvmVkMnFGoyv60jQciWvCFSYkpv2zxAOrmiCjgeYhU
|
||||||
|
+d8B64qqWmnvdeLl8XGdBYN6nz+vWtWNDi/YuoGI2qhcuiikKvk0Ofmxx3+s4NHS
|
||||||
|
DqdFfv3CbA5BFBLaHnFHVn+jocEgafOWUjruYcwrUcZuCr8Oy8KLqz6w5Xta/B7x
|
||||||
|
0Lyx3zvHAgMBAAECggEADQw5ACxWCVnVAqQbZ5gUeb9BhDGE09HuRnmPBgFo+KSI
|
||||||
|
P1m7WkNjbP/nM70llobxNfx5HOsGgOqUvXZ+X94eikqtCczD3ND9rmMUOhNomsq4
|
||||||
|
N3k+05aZvJxr26h0ecqTWpWAfoTupbv/cvexdtHmyNWiB2q6NK7rpztoLPk9HA+q
|
||||||
|
OzVH/qFbtqr1cQJijyrow97A/Yi2f3Kvp7irlLbH0QxxF9jPW/KDn2FIzycoFUtq
|
||||||
|
NfuXkUpRkVA82lOyL80uYfQmNkM5/nKJxCTdUtSvA58a2jUC8xVH372kSKikTh6o
|
||||||
|
clIR8vnvp2aFOrlyz3WfZGZgTo8/MuXP69aujwNgQQKBgQDItvqbcmHjWLIEuheS
|
||||||
|
ahwIlFFhRR24ytsoRm1HVytBa+tmm56WjPV4chutrEz6IjPd8AvICwpQfCu17iUn
|
||||||
|
7HM5a0hMctFtVxYuHGnMszD1KpgEByPnv59pPnTbvhqlnRpNR1aM2KVxAXAKSOgY
|
||||||
|
8u+FA3c4wgUpA3z0l7Db33CUJwKBgQDCuRG8+8+HbQdMmct2+YbId/LSyvnoa9uS
|
||||||
|
LYXn0WboCOZkEv0KxTjfn2wuLn0WaGG44ucvaFE4hDa7d6cIgrpBLD04rS8xSwa7
|
||||||
|
uEQeRrThIn7Gv/RpcTxk0TASIEN2zIi18OV0Wx92wTTv34omFxZLPit9UgiCJM7i
|
||||||
|
nAFUD6K/YQKBgC33geNRyctIR9S/TaCxfmQUm6KcMpdcld5eaq547yYXchzYrPQr
|
||||||
|
qhgAggg/Oo3agWhljj0tEhqmpVgQByBijWzr/e3MKdxRonnC9hP0QdUUASaDAB0W
|
||||||
|
DIsMy7R7kBy3owtpuA+fmhwMST2Bvu3fzSz4QziTbp0a+GYHy3A/dsfnAoGAPYiK
|
||||||
|
SHQyopMbqWM4XsJ/iz4MZ/xoeMAMxObJ1/XeVRjq5VjyycKFNHWGlBlwwfH+X5Sk
|
||||||
|
heCrOfbd7OPkztWw0gOO3SgtL6CL4iparE6fvj1OXrQuIlv8P8ezLycu6o277fLQ
|
||||||
|
L7LUAI0Rk3PKjjrheqmMyK9xrN7A2e9+o/fE8EECgYAx3IziYqFfD4KzgmcM6MKx
|
||||||
|
t4/SVFXBRLzse8AB3V6qSEwgCaUfeuj0Qq93nrkTIodHFWXuFoQTgQrA29VWbK6x
|
||||||
|
PSwjdVNwYES+Hg+LbXP8Fo+u5sGhcWLzWdmFp3UdUm5Mv76Oo+MriZNnS4RQiX0+
|
||||||
|
Y8PiIt3YYCsowmchtEggaQ==
|
||||||
|
-----END PRIVATE KEY-----)";
|
||||||
|
constexpr std::string pub_key_b =
|
||||||
|
R"(-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmKvEDTl2UaAInUe3ChPW
|
||||||
|
8q/vVnpDzDQzZGik40VKF4/JVIJ6N8ubSAxCKoXL+LYUywMc0A+Dfm1QN1xdWTH5
|
||||||
|
thpjNDutQLaSsC+nYgXhqQk7p8M5fZ603mnJEJsKkcJZXN5Fv56bnTZ9djPZuMLI
|
||||||
|
CyvfI7smOqWQHk5QL5lZDJxRqMr+tI0HIlrwhUmJKb9s8QDq5ogo4HmIVPnfAeuK
|
||||||
|
qlpp73Xi5fFxnQWDep8/r1rVjQ4v2LqBiNqoXLoopCr5NDn5scd/rODR0g6nRX79
|
||||||
|
wmwOQRQS2h5xR1Z/o6HBIGnzllI67mHMK1HGbgq/DsvCi6s+sOV7Wvwe8dC8sd87
|
||||||
|
xwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----)";
|
||||||
|
|
||||||
|
|
||||||
// Demonstrate some basic assertions.
|
// Demonstrate some basic assertions.
|
||||||
TEST(AuthorizerTest, BasicAssertions) {
|
TEST(TokenTest, TwoWay) {
|
||||||
// Expect two strings not to be equal.
|
constexpr std::string issuer = "james-keycloak";
|
||||||
EXPECT_STRNE("hello", "world");
|
constexpr std::string username = "james";
|
||||||
// Expect equality.
|
constexpr
|
||||||
EXPECT_EQ(7 * 6, 42);
|
const auto token = gen_token(
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue