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)
|
||||
|
||||
find_package(OpenSSL)
|
||||
find_package(yaml-cpp)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
|
|
@ -14,12 +15,19 @@ target_include_directories(utils PUBLIC
|
|||
)
|
||||
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
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/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)
|
||||
target_include_directories(gen-token PUBLIC
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Authentication using JWTs for the mosquitto mqtt broker.
|
|||
|
||||
## 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
auth_plugin /home/jimmy/Develop/mosquitto-plugin/build/libj7s-plugin.so
|
||||
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
|
||||
protocol mqtt
|
||||
allow_anonymous false
|
||||
auth_plugin /home/jimmy/Develop/mosquitto-plugin/build/libj7s-plugin.so
|
||||
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
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
#include <forward_list>
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using time_T = std::chrono::time_point<std::chrono::system_clock>;
|
||||
|
||||
// A list with easily checkable contents.
|
||||
class AuthList
|
||||
{
|
||||
public:
|
||||
AuthList();
|
||||
|
||||
void add(const std::string& username);
|
||||
void add(const std::string& username, const time_T& expr_time);
|
||||
void remove(const std::string& username);
|
||||
bool confirm(const std::string& username);
|
||||
|
||||
private:
|
||||
std::forward_list<std::string> _allowedUsernames;
|
||||
std::map<std::string, time_T> _map;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include <j7s-plugin/AuthList.hpp>
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -22,7 +24,7 @@
|
|||
class Authorizer
|
||||
{
|
||||
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);
|
||||
void add_unknown(const std::string& username);
|
||||
bool is_unknown(const std::string& username);
|
||||
|
|
@ -35,6 +37,8 @@ private:
|
|||
AuthList _readList;
|
||||
AuthList _unknownList;
|
||||
|
||||
YAML::Node _aclFile;
|
||||
|
||||
std::string _pub_key;
|
||||
std::string _issuer;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
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 & username,
|
||||
const std::string & issuer,
|
||||
|
|
|
|||
|
|
@ -14,36 +14,38 @@
|
|||
#include <algorithm>
|
||||
#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?
|
||||
// If not add it.
|
||||
if (not confirm(username))
|
||||
{
|
||||
_allowedUsernames.emplace_front(username);
|
||||
}
|
||||
// Add the user to the list or update it's expr time if
|
||||
// it's already there.
|
||||
_map[username] = expr_time;
|
||||
}
|
||||
|
||||
void AuthList::remove(const std::string & username)
|
||||
{
|
||||
// Is the user in the list?
|
||||
// Is so, remove it,
|
||||
if (confirm(username))
|
||||
{
|
||||
_allowedUsernames.remove(username);
|
||||
}
|
||||
// Remove the user
|
||||
_map.erase(username);
|
||||
}
|
||||
|
||||
bool AuthList::confirm(const std::string & username)
|
||||
{
|
||||
// Is the user in the list?
|
||||
const auto found =
|
||||
std::find(std::begin(_allowedUsernames), std::end(_allowedUsernames), username);
|
||||
if (found != std::end(_allowedUsernames))
|
||||
// Is the user in the map?
|
||||
const auto iter = _map.find(username);
|
||||
|
||||
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 false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,21 @@
|
|||
#include <j7s-plugin/AuthList.hpp>
|
||||
#include <j7s-plugin/Authorizer.hpp>
|
||||
|
||||
Authorizer::Authorizer(const std::string & pub_key, const std::string & issuer) :
|
||||
_pub_key{pub_key}, _issuer{issuer}
|
||||
#include <tuple>
|
||||
|
||||
// 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)
|
||||
{
|
||||
_unknownList.add(username);
|
||||
_unknownList.add(username, time_T::max());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const auto validated = validate(token, username, _issuer, _pub_key);
|
||||
const auto [validated, expr_time] = validate(token, username, _issuer, _pub_key);
|
||||
if (not validated)
|
||||
{
|
||||
std::cerr << "Not validated." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Check ACL file to see which one.
|
||||
_writeList.add(username);
|
||||
_readList.add(username);
|
||||
// Check the ACL file.
|
||||
// TODO: Make sure default is in ACL file.
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
bool Authorizer::can_read(const std::string & username)
|
||||
{
|
||||
return _readList.confirm(username);
|
||||
|
|
@ -64,3 +86,20 @@ void Authorizer::logout(const std::string & username)
|
|||
_readList.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/Authorizer.hpp>
|
||||
|
||||
#include <j7s-plugin/utils.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
// Mosquitto Globals
|
||||
static mosquitto_plugin_id_t * plugin_id = nullptr;
|
||||
|
|
@ -41,7 +45,7 @@ int mosquitto_plugin_init(
|
|||
{
|
||||
plugin_id = identifier;
|
||||
|
||||
if (option_count != 2)
|
||||
if (option_count < 3)
|
||||
{
|
||||
mosquitto_log_printf(MOSQ_LOG_ERR, "Missing an option. Found: %d", option_count);
|
||||
return MOSQ_ERR_INVAL;
|
||||
|
|
@ -49,12 +53,13 @@ int mosquitto_plugin_init(
|
|||
|
||||
std::string public_key;
|
||||
std::string issuer;
|
||||
std::filesystem::path aclFilePath;
|
||||
for (int index = 0; index < option_count; index++)
|
||||
{
|
||||
const auto key = std::string(options[index].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())
|
||||
{
|
||||
mosquitto_log_printf(MOSQ_LOG_ERR, "Could not read public key.");
|
||||
|
|
@ -71,9 +76,20 @@ int mosquitto_plugin_init(
|
|||
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.
|
||||
mosquitto_callback_register(
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ std::optional<std::string> read_key(const std::string & key_file)
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
bool validate(
|
||||
std::tuple<bool, std::chrono::time_point<std::chrono::system_clock>> validate(
|
||||
const std::string & token,
|
||||
const std::string & username,
|
||||
const std::string & issuer,
|
||||
|
|
@ -50,7 +50,7 @@ bool validate(
|
|||
catch (jwt::error::token_verification_exception & exception)
|
||||
{
|
||||
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();
|
||||
|
||||
|
|
@ -58,22 +58,34 @@ bool validate(
|
|||
if (not claims.contains("upn"))
|
||||
{
|
||||
std::cerr << "Missing upn." << std::endl;
|
||||
return false;
|
||||
return std::make_tuple(false, std::chrono::system_clock::now());
|
||||
}
|
||||
if (claims["upn"].as_string() != username)
|
||||
{
|
||||
std::cerr << "Wrong username." << std::endl;
|
||||
return false;
|
||||
return std::make_tuple(false, std::chrono::system_clock::now());
|
||||
}
|
||||
|
||||
// Check for mqtt-write claim value.
|
||||
if (not claims.contains("mqtt"))
|
||||
{
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
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.
|
||||
TEST(AuthorizerTest, BasicAssertions) {
|
||||
// Expect two strings not to be equal.
|
||||
EXPECT_STRNE("hello", "world");
|
||||
// Expect equality.
|
||||
EXPECT_EQ(7 * 6, 42);
|
||||
TEST(TokenTest, TwoWay) {
|
||||
constexpr std::string issuer = "james-keycloak";
|
||||
constexpr std::string username = "james";
|
||||
constexpr
|
||||
const auto token = gen_token(
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue