mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 12:33:44 +02:00
Big SSO update
make things hopefully work
This commit is contained in:
parent
81fda3f5b8
commit
4f521baafd
7 changed files with 144 additions and 80 deletions
|
@ -49,6 +49,9 @@ void DB::initNetwork(nlohmann::json &network)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
if (!network.count("dns")) network["dns"] = nlohmann::json::array();
|
if (!network.count("dns")) network["dns"] = nlohmann::json::array();
|
||||||
|
if (!network.count("ssoEnabled")) network["ssoEnabled"] = false;
|
||||||
|
if (!network.count("clientId")) network["clientId"] = "";
|
||||||
|
if (!network.count("authorizationEndpoint")) network["authorizationEndpoint"] = "";
|
||||||
|
|
||||||
network["objtype"] = "network";
|
network["objtype"] = "network";
|
||||||
}
|
}
|
||||||
|
@ -136,7 +139,6 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t mem
|
||||||
if (m == nw->members.end())
|
if (m == nw->members.end())
|
||||||
return false;
|
return false;
|
||||||
member = m->second;
|
member = m->second;
|
||||||
updateMemberOnLoad(networkId, memberId, member);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +162,6 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t mem
|
||||||
if (m == nw->members.end())
|
if (m == nw->members.end())
|
||||||
return false;
|
return false;
|
||||||
member = m->second;
|
member = m->second;
|
||||||
updateMemberOnLoad(networkId, memberId, member);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +182,6 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohma
|
||||||
network = nw->config;
|
network = nw->config;
|
||||||
for(auto m=nw->members.begin();m!=nw->members.end();++m) {
|
for(auto m=nw->members.begin();m!=nw->members.end();++m) {
|
||||||
members.push_back(m->second);
|
members.push_back(m->second);
|
||||||
updateMemberOnLoad(networkId, m->first, members.back());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
virtual void eraseNetwork(const uint64_t networkId) = 0;
|
virtual void eraseNetwork(const uint64_t networkId) = 0;
|
||||||
virtual void eraseMember(const uint64_t networkId,const uint64_t memberId) = 0;
|
virtual void eraseMember(const uint64_t networkId,const uint64_t memberId) = 0;
|
||||||
virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) = 0;
|
virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) = 0;
|
||||||
virtual void updateMemberOnLoad(const uint64_t networkId, const uint64_t memberId, nlohmann::json &member) {}
|
virtual std::string getSSOAuthURL(const nlohmann::json &member) { return ""; }
|
||||||
|
|
||||||
inline void addListener(DB::ChangeListener *const listener)
|
inline void addListener(DB::ChangeListener *const listener)
|
||||||
{
|
{
|
||||||
|
|
|
@ -125,6 +125,18 @@ bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,std::vect
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string DBMirrorSet::getSSOAuthURL(const nlohmann::json &member)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> l(_dbs_l);
|
||||||
|
for(auto d=_dbs.begin();d!=_dbs.end();++d) {
|
||||||
|
std::string url = (*d)->getSSOAuthURL(member);
|
||||||
|
if (!url.empty()) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
void DBMirrorSet::networks(std::set<uint64_t> &networks)
|
void DBMirrorSet::networks(std::set<uint64_t> &networks)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> l(_dbs_l);
|
std::lock_guard<std::mutex> l(_dbs_l);
|
||||||
|
|
|
@ -51,6 +51,8 @@ public:
|
||||||
virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member);
|
virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member);
|
||||||
virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId);
|
virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId);
|
||||||
|
|
||||||
|
std::string getSSOAuthURL(const nlohmann::json &member);
|
||||||
|
|
||||||
inline void addDB(const std::shared_ptr<DB> &db)
|
inline void addDB(const std::shared_ptr<DB> &db)
|
||||||
{
|
{
|
||||||
db->addListener(this);
|
db->addListener(this);
|
||||||
|
|
|
@ -1326,16 +1326,11 @@ void EmbeddedNetworkController::_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64_t authenticationExpiryTime = -1;
|
// Should we check SSO Stuff?
|
||||||
if (!member["authenticationExpiryTime"].is_null()) {
|
// If network is configured with SSO, and the member is not marked exempt: yes
|
||||||
authenticationExpiryTime = member["authenticationExpiryTime"];
|
// Otherwise no, we use standard auth logic.
|
||||||
}
|
bool networkSSOEnabled = OSUtils::jsonBool(network["ssoEnabled"], false);
|
||||||
|
bool memberSSOExempt = OSUtils::jsonBool(member["ssoExempt"], false);
|
||||||
std::string authenticationURL = "";
|
|
||||||
if (!member["authenticationURL"].is_null()) {
|
|
||||||
authenticationURL = member["authenticationURL"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (authorized) {
|
if (authorized) {
|
||||||
// Update version info and meta-data if authorized and if this is a genuine request
|
// Update version info and meta-data if authorized and if this is a genuine request
|
||||||
if (requestPacketId) {
|
if (requestPacketId) {
|
||||||
|
@ -1362,13 +1357,19 @@ void EmbeddedNetworkController::_request(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((authenticationExpiryTime >= 0)&&(authenticationExpiryTime < now)) {
|
if (networkSSOEnabled && !memberSSOExempt) {
|
||||||
|
int64_t authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0);
|
||||||
|
if ((authenticationExpiryTime == 0) || (authenticationExpiryTime < now)) {
|
||||||
Dictionary<1024> authInfo;
|
Dictionary<1024> authInfo;
|
||||||
if (!authenticationURL.empty())
|
std::string authenticationURL = _db.getSSOAuthURL(member);
|
||||||
|
if (!authenticationURL.empty()) {
|
||||||
authInfo.add("aU", authenticationURL.c_str());
|
authInfo.add("aU", authenticationURL.c_str());
|
||||||
|
}
|
||||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes());
|
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If they are not authorized, STOP!
|
// If they are not authorized, STOP!
|
||||||
DB::cleanMember(member);
|
DB::cleanMember(member);
|
||||||
|
@ -1406,8 +1407,11 @@ void EmbeddedNetworkController::_request(
|
||||||
Utils::scopy(nc->name,sizeof(nc->name),OSUtils::jsonString(network["name"],"").c_str());
|
Utils::scopy(nc->name,sizeof(nc->name),OSUtils::jsonString(network["name"],"").c_str());
|
||||||
nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU);
|
nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU);
|
||||||
nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL);
|
nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL);
|
||||||
Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), authenticationURL.c_str());
|
|
||||||
nc->authenticationExpiryTime = authenticationExpiryTime;
|
// TODO: Decide what to do with these, or if to remove them
|
||||||
|
// they don't make sense here as is.
|
||||||
|
// Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), authenticationURL.c_str());
|
||||||
|
// nc->authenticationExpiryTime = authenticationExpiryTime;
|
||||||
|
|
||||||
std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],""));
|
std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],""));
|
||||||
if (rtt.length() == 10) {
|
if (rtt.length() == 10) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ using json = nlohmann::json;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const int DB_MINIMUM_VERSION = 19;
|
static const int DB_MINIMUM_VERSION = 20;
|
||||||
|
|
||||||
static const char *_timestr()
|
static const char *_timestr()
|
||||||
{
|
{
|
||||||
|
@ -309,81 +309,94 @@ void PostgreSQL::nodeIsOnline(const uint64_t networkId, const uint64_t memberId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostgreSQL::updateMemberOnLoad(const uint64_t networkId, const uint64_t memberId, nlohmann::json &member)
|
std::string PostgreSQL::getSSOAuthURL(const nlohmann::json &member)
|
||||||
{
|
{
|
||||||
|
// NONCE is just a random character string. no semantic meaning
|
||||||
|
// state = HMAC SHA384 of Nonce based on shared sso key
|
||||||
|
//
|
||||||
|
// need nonce timeout in database? make sure it's used within X time
|
||||||
|
// X is 5 minutes for now. Make configurable later?
|
||||||
|
//
|
||||||
|
// how do we tell when a nonce is used? if auth_expiration_time is set
|
||||||
|
std::string networkId = member["nwid"];
|
||||||
|
std::string memberId = member["id"];
|
||||||
|
char authenticationURL[4096] = {0};
|
||||||
|
|
||||||
const uint64_t nwid = OSUtils::jsonIntHex(member["nwid"],0ULL);
|
fprintf(stderr, "PostgreSQL::updateMemberOnLoad: %s-%s\n", networkId.c_str(), memberId.c_str());
|
||||||
const uint64_t id = OSUtils::jsonIntHex(member["id"],0ULL);
|
|
||||||
char nwids[24],ids[24];
|
|
||||||
OSUtils::ztsnprintf(nwids, sizeof(nwids), "%.16llx", nwid);
|
|
||||||
OSUtils::ztsnprintf(ids, sizeof(ids), "%.10llx", id);
|
|
||||||
|
|
||||||
fprintf(stderr, "PostgreSQL::updateMemberOnLoad: %s-%s\n", nwids, ids);
|
|
||||||
bool have_auth = false;
|
bool have_auth = false;
|
||||||
try {
|
try {
|
||||||
auto c = _pool->borrow();
|
auto c = _pool->borrow();
|
||||||
pqxx::work w(*c->c);
|
pqxx::work w(*c->c);
|
||||||
|
|
||||||
pqxx::result r = w.exec_params("SELECT org.client_id, org.authorization_endpoint "
|
std::string nonce = "";
|
||||||
|
|
||||||
|
// find an unused nonce, if one exists.
|
||||||
|
pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry "
|
||||||
|
"WHERE network_id = $1 AND member_id = $2 AND "
|
||||||
|
"AND authentication_expiry_time IS NULL AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiry",
|
||||||
|
networkId, memberId);
|
||||||
|
|
||||||
|
if (r.size() == 1) {
|
||||||
|
// we have an existing nonce. Use it
|
||||||
|
nonce = r.at(0)[0].as<std::string>();
|
||||||
|
} else if (r.empty()) {
|
||||||
|
// create a nonce
|
||||||
|
char randBuf[16] = {0};
|
||||||
|
Utils::getSecureRandom(randBuf, 16);
|
||||||
|
char nonceBuf[256] = {0};
|
||||||
|
Utils::hex(randBuf, sizeof(randBuf), nonceBuf);
|
||||||
|
nonce = std::string(nonceBuf);
|
||||||
|
|
||||||
|
pqxx::result ir = w.exec_params0("INSERT INTO ztc_sso_expiry "
|
||||||
|
"(nonce, nonce_expiry, network_id, member_id) VALUES "
|
||||||
|
"($1, TO_TIMESTAMP($2::double precision/1000) $3, $4)",
|
||||||
|
nonce, OSUtils::now() + 300000, networkId, memberId);
|
||||||
|
} else {
|
||||||
|
// > 1 ?!? Thats an error!
|
||||||
|
fprintf(stderr, "> 1 unused nonce!\n");
|
||||||
|
exit(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = w.exec_params("SELECT org.client_id, org.authorization_endpoint "
|
||||||
"FROM ztc_network AS nw, ztc_org AS org "
|
"FROM ztc_network AS nw, ztc_org AS org "
|
||||||
"WHERE nw.id = $1 AND nw.sso_enabled = true AND org.owner_id = nw.owner_id", nwids);
|
"WHERE nw.id = $1 AND nw.sso_enabled = true AND org.owner_id = nw.owner_id", networkId);
|
||||||
|
|
||||||
std::string client_id = "";
|
std::string client_id = "";
|
||||||
std::string authorization_endpoint = "";
|
std::string authorization_endpoint = "";
|
||||||
|
|
||||||
if (r.size() == 1) {
|
if (r.size() == 1) {
|
||||||
// only one should exist
|
client_id = r.at(0)[0].as<std::string>();
|
||||||
pqxx::row row = r.at(0);
|
authorization_endpoint = r.at(0)[1].as<std::string>();
|
||||||
client_id = row[0].as<std::string>();
|
|
||||||
authorization_endpoint = row[1].as<std::string>();
|
|
||||||
} else if (r.size() > 1) {
|
} else if (r.size() > 1) {
|
||||||
fprintf(stderr, "ERROR: More than one auth endpoint for an organization?!?!? NetworkID: %s\n", nwids);
|
fprintf(stderr, "ERROR: More than one auth endpoint for an organization?!?!? NetworkID: %s\n", networkId.c_str());
|
||||||
}
|
}
|
||||||
// no catch all else because we don't actually care if no records exist here. just continue as normal.
|
// no catch all else because we don't actually care if no records exist here. just continue as normal.
|
||||||
|
|
||||||
if ((!client_id.empty())&&(!authorization_endpoint.empty())) {
|
if ((!client_id.empty())&&(!authorization_endpoint.empty())) {
|
||||||
pqxx::row r2 = w.exec_params1(
|
|
||||||
"SELECT e.nonce, EXTRACT(EPOCH FROM e.authentication_expiry_time AT TIME ZONE 'UTC')*1000 as authentication_expiry_time"
|
|
||||||
"FROM ztc_sso_expiry e "
|
|
||||||
"WHERE e.network_id = $1 AND e.member_id = $2 "
|
|
||||||
"ORDER BY n.authentication_expiry_time DESC LIMIT 1", nwids, ids);
|
|
||||||
|
|
||||||
std::string nonce = r2[0].as<std::string>();
|
|
||||||
int64_t authentication_expiry_time = r2[0].as<int64_t>();
|
|
||||||
if ((authentication_expiry_time >= 0)&&(!nonce.empty())) {
|
|
||||||
have_auth = true;
|
have_auth = true;
|
||||||
|
|
||||||
uint8_t state[48];
|
uint8_t state[48];
|
||||||
HMACSHA384(_ssoPsk, nonce.data(), (unsigned int)nonce.length(), state);
|
HMACSHA384(_ssoPsk, nonce.data(), (unsigned int)nonce.length(), state);
|
||||||
char state_hex[256];
|
char state_hex[256];
|
||||||
Utils::hex(state, 48, state_hex);
|
Utils::hex(state, 48, state_hex);
|
||||||
char authenticationURL[4096];
|
|
||||||
const char *redirect_url = "redirect_uri=http%3A%2F%2Fmy.zerotier.com%2Fapi%2Fnetwork%2Fsso-auth"; // TODO: this should be configurable
|
const char *redirect_url = "redirect_uri=https%3A%2F%2Fmy.zerotier.com%2Fapi%2Fnetwork%2Fsso-auth"; // TODO: this should be configurable
|
||||||
OSUtils::ztsnprintf(authenticationURL, sizeof(authenticationURL),
|
OSUtils::ztsnprintf(authenticationURL, sizeof(authenticationURL),
|
||||||
"%s?response_type=id_token&response_mode=form_post&scope=openid+email+profile&redriect_uri=%s&nonce=%s&state=%s&client_id=%s",
|
"%s?response_type=id_token&response_mode=form_post&scope=openid+email+profile&redriect_uri=%s&nonce=%s&state=%s&client_id=%s",
|
||||||
authorization_endpoint.c_str(),
|
authorization_endpoint.c_str(),
|
||||||
redirect_url,
|
redirect_url,
|
||||||
nonce.c_str(),
|
nonce.c_str(),
|
||||||
state_hex, // NOTE: should these be URL escaped? Don't think there's a risk as they are not user definable.
|
state_hex,
|
||||||
client_id.c_str());
|
client_id.c_str());
|
||||||
|
|
||||||
member["authenticationExpiryTime"] = authentication_expiry_time;
|
|
||||||
member["authenticationURL"] = authenticationURL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
member["authenticationExpiryTime"] = -1LL;
|
|
||||||
member["authenticationURL"] = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_pool->unborrow(c);
|
_pool->unborrow(c);
|
||||||
|
|
||||||
} catch (sw::redis::Error &e) {
|
|
||||||
fprintf(stderr, "ERROR: Error updating member on load, in Redis: %s\n", e.what());
|
|
||||||
exit(-1);
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
fprintf(stderr, "ERROR: Error updating member on load: %s\n", e.what());
|
fprintf(stderr, "ERROR: Error updating member on load: %s\n", e.what());
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return std::string(authenticationURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostgreSQL::initializeNetworks()
|
void PostgreSQL::initializeNetworks()
|
||||||
|
@ -398,13 +411,15 @@ void PostgreSQL::initializeNetworks()
|
||||||
pqxx::work w{*c->c};
|
pqxx::work w{*c->c};
|
||||||
pqxx::result r = w.exec_params("SELECT id, EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000 as creation_time, capabilities, "
|
pqxx::result r = w.exec_params("SELECT id, EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000 as creation_time, capabilities, "
|
||||||
"enable_broadcast, EXTRACT(EPOCH FROM last_modified AT TIME ZONE 'UTC')*1000 AS last_modified, mtu, multicast_limit, name, private, remote_trace_level, "
|
"enable_broadcast, EXTRACT(EPOCH FROM last_modified AT TIME ZONE 'UTC')*1000 AS last_modified, mtu, multicast_limit, name, private, remote_trace_level, "
|
||||||
"remote_trace_target, revision, rules, tags, v4_assign_mode, v6_assign_mode FROM ztc_network "
|
"remote_trace_target, revision, rules, tags, v4_assign_mode, v6_assign_mode, sso_enabled FROM ztc_network "
|
||||||
"WHERE deleted = false AND controller_id = $1", _myAddressStr);
|
"WHERE deleted = false AND controller_id = $1", _myAddressStr);
|
||||||
|
|
||||||
for (auto row = r.begin(); row != r.end(); row++) {
|
for (auto row = r.begin(); row != r.end(); row++) {
|
||||||
json empty;
|
json empty;
|
||||||
json config;
|
json config;
|
||||||
|
|
||||||
|
initNetwork(config);
|
||||||
|
|
||||||
std::string nwid = row[0].as<std::string>();
|
std::string nwid = row[0].as<std::string>();
|
||||||
|
|
||||||
networkSet.insert(nwid);
|
networkSet.insert(nwid);
|
||||||
|
@ -458,6 +473,7 @@ void PostgreSQL::initializeNetworks()
|
||||||
config["tags"] = json::parse(row[13].as<std::string>());
|
config["tags"] = json::parse(row[13].as<std::string>());
|
||||||
config["v4AssignMode"] = json::parse(row[14].as<std::string>());
|
config["v4AssignMode"] = json::parse(row[14].as<std::string>());
|
||||||
config["v6AssignMode"] = json::parse(row[15].as<std::string>());
|
config["v6AssignMode"] = json::parse(row[15].as<std::string>());
|
||||||
|
config["ssoEnabled"] = row[16].as<bool>();
|
||||||
config["objtype"] = "network";
|
config["objtype"] = "network";
|
||||||
config["ipAssignmentPools"] = json::array();
|
config["ipAssignmentPools"] = json::array();
|
||||||
config["routes"] = json::array();
|
config["routes"] = json::array();
|
||||||
|
@ -514,6 +530,19 @@ void PostgreSQL::initializeNetworks()
|
||||||
config["dns"] = obj;
|
config["dns"] = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r2 = w.exec_params("SELECT org.client_id, org.authorization_endpoint "
|
||||||
|
"FROM ztc_network nw "
|
||||||
|
"INNER JOIN ztc_org org "
|
||||||
|
" ON org.owner_id = nw.owner_id "
|
||||||
|
"WHERE nw.id = $1 AND nw.sso_enabled = true", nwid);
|
||||||
|
|
||||||
|
if (r2.size() == 1) {
|
||||||
|
// only one should exist
|
||||||
|
pqxx::row row = r.at(0);
|
||||||
|
config["clientId"] = row[0].as<std::string>();
|
||||||
|
config["authorizationEndpoint"] = row[1].as<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
_networkChanged(empty, config, false);
|
_networkChanged(empty, config, false);
|
||||||
fprintf(stderr, "Initialized Network: %s\n", nwid.c_str());
|
fprintf(stderr, "Initialized Network: %s\n", nwid.c_str());
|
||||||
}
|
}
|
||||||
|
@ -549,7 +578,7 @@ void PostgreSQL::initializeMembers()
|
||||||
" (EXTRACT(EPOCH FROM m.last_authorized_time AT TIME ZONE 'UTC')*1000)::bigint, "
|
" (EXTRACT(EPOCH FROM m.last_authorized_time AT TIME ZONE 'UTC')*1000)::bigint, "
|
||||||
" (EXTRACT(EPOCH FROM m.last_deauthorized_time AT TIME ZONE 'UTC')*1000)::bigint, "
|
" (EXTRACT(EPOCH FROM m.last_deauthorized_time AT TIME ZONE 'UTC')*1000)::bigint, "
|
||||||
" m.remote_trace_level, m.remote_trace_target, m.tags, m.v_major, m.v_minor, m.v_rev, m.v_proto, "
|
" m.remote_trace_level, m.remote_trace_target, m.tags, m.v_major, m.v_minor, m.v_rev, m.v_proto, "
|
||||||
" m.no_auto_assign_ips, m.revision "
|
" m.no_auto_assign_ips, m.revision, sso_exempt "
|
||||||
"FROM ztc_member m "
|
"FROM ztc_member m "
|
||||||
"INNER JOIN ztc_network n "
|
"INNER JOIN ztc_network n "
|
||||||
" ON n.id = m.network_id "
|
" ON n.id = m.network_id "
|
||||||
|
@ -559,6 +588,8 @@ void PostgreSQL::initializeMembers()
|
||||||
json empty;
|
json empty;
|
||||||
json config;
|
json config;
|
||||||
|
|
||||||
|
initMember(config);
|
||||||
|
|
||||||
std::string memberId = row[0].as<std::string>();
|
std::string memberId = row[0].as<std::string>();
|
||||||
std::string networkId = row[1].as<std::string>();
|
std::string networkId = row[1].as<std::string>();
|
||||||
|
|
||||||
|
@ -627,13 +658,28 @@ void PostgreSQL::initializeMembers()
|
||||||
config["revision"] = 0ULL;
|
config["revision"] = 0ULL;
|
||||||
//fprintf(stderr, "Error updating revision (member): %s\n", PQgetvalue(res, i, 17));
|
//fprintf(stderr, "Error updating revision (member): %s\n", PQgetvalue(res, i, 17));
|
||||||
}
|
}
|
||||||
|
config["ssoExempt"] = row[18].as<bool>();
|
||||||
|
|
||||||
|
config["authenticationExpiryTime"] = 0LL;
|
||||||
|
pqxx::result authRes = w.exec_params(
|
||||||
|
"SELECT (EXTRACT(EPOCH FROM e.authentication_expiry_time)*1000)::bigint "
|
||||||
|
"FROM ztc_sso_expiry e "
|
||||||
|
"INNER JOIN ztc_network n "
|
||||||
|
" ON n.id = e.network_id "
|
||||||
|
"WHERE e.network_id = $1 AND e.member_id = $2 AND n.sso_enabled = TRUE "
|
||||||
|
"ORDER BY e.authentication_expiry_time LIMIT 1", networkId, memberId);
|
||||||
|
|
||||||
|
if (authRes.size() == 1) {
|
||||||
|
// there is an expiry time record
|
||||||
|
config["authenticationExpiryTime"] = authRes.at(0)[0].as<int64_t>();
|
||||||
|
}
|
||||||
|
|
||||||
config["objtype"] = "member";
|
config["objtype"] = "member";
|
||||||
config["ipAssignments"] = json::array();
|
config["ipAssignments"] = json::array();
|
||||||
|
|
||||||
pqxx::result r2 = w.exec("SELECT DISTINCT address "
|
pqxx::result r2 = w.exec_params("SELECT DISTINCT address "
|
||||||
"FROM ztc_member_ip_assignment "
|
"FROM ztc_member_ip_assignment "
|
||||||
"WHERE member_id = "+w.quote(memberId)+" AND network_id = "+w.quote(networkId));
|
"WHERE member_id = $1 AND network_id = $2", memberId, networkId);
|
||||||
|
|
||||||
|
|
||||||
for (auto row2 = r2.begin(); row2 != r2.end(); row2++) {
|
for (auto row2 = r2.begin(); row2 != r2.end(); row2++) {
|
||||||
std::string ipaddr = row2[0].as<std::string>();
|
std::string ipaddr = row2[0].as<std::string>();
|
||||||
|
|
|
@ -107,7 +107,7 @@ public:
|
||||||
virtual void eraseNetwork(const uint64_t networkId);
|
virtual void eraseNetwork(const uint64_t networkId);
|
||||||
virtual void eraseMember(const uint64_t networkId, const uint64_t memberId);
|
virtual void eraseMember(const uint64_t networkId, const uint64_t memberId);
|
||||||
virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress);
|
virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress);
|
||||||
virtual void updateMemberOnLoad(const uint64_t networkId, const uint64_t memberId, nlohmann::json &member);
|
virtual std::string getSSOAuthURL(const nlohmann::json &member);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct _PairHasher
|
struct _PairHasher
|
||||||
|
|
Loading…
Add table
Reference in a new issue