@ -429,149 +429,168 @@ void PostgreSQL::initializeNetworks()
std : : unordered_set < std : : string > networkSet ;
fprintf ( stderr , " Initializing Networks... \n " ) ;
auto c = _pool - > borrow ( ) ;
pqxx : : work w { * c - > c } ;
pqxx : : result r = w . exec_params ( " SELECT id, (EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000)::bigint as creation_time, capabilities, "
char qbuf [ 2048 ] = { 0 } ;
sprintf ( qbuf , " SELECT id, (EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000)::bigint as creation_time, capabilities, "
" enable_broadcast, (EXTRACT(EPOCH FROM last_modified AT TIME ZONE 'UTC')*1000)::bigint AS last_modified, mtu, multicast_limit, name, private, remote_trace_level, "
" 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 ) ;
for ( auto row = r . begin ( ) ; row ! = r . end ( ) ; row + + ) {
" WHERE deleted = false AND controller_id = '%s' " , _myAddressStr . c_str ( ) ) ;
auto c = _pool - > borrow ( ) ;
auto c2 = _pool - > borrow ( ) ;
pqxx : : work w { * c - > c } ;
auto stream = pqxx : : stream_from : : query ( w , qbuf ) ;
std : : tuple <
std : : string // network ID
, std : : optional < int64_t > // creationTime
, std : : optional < std : : string > // capabilities
, std : : optional < bool > // enableBroadcast
, std : : optional < uint64_t > // lastModified
, std : : optional < int > // mtu
, std : : optional < int > // multicastLimit
, std : : optional < std : : string > // name
, bool // private
, std : : optional < int > // remoteTraceLevel
, std : : optional < std : : string > // remoteTraceTarget
, std : : optional < uint64_t > // revision
, std : : optional < std : : string > // rules
, std : : optional < std : : string > // tags
, std : : optional < std : : string > // v4AssignMode
, std : : optional < std : : string > // v6AssignMode
, std : : optional < bool > // ssoEnabled
> row ;
while ( stream > > row ) {
json empty ;
json config ;
initNetwork ( config ) ;
std : : string nwid = row [ 0 ] . as < std : : string > ( ) ;
networkSet . insert ( nwid ) ;
config [ " id " ] = nwid ;
config [ " nwid " ] = nwid ;
if ( ! row [ 1 ] . is_null ( ) ) {
config [ " creationTime " ] = row [ 1 ] . as < int64_t > ( ) ;
} else {
config [ " creationTime " ] = 0ULL ;
}
config [ " capabilities " ] = row [ 2 ] . as < std : : string > ( ) ;
config [ " enableBroadcast " ] = row [ 3 ] . as < bool > ( ) ;
if ( ! row [ 4 ] . is_null ( ) ) {
config [ " lastModified " ] = row [ 4 ] . as < uint64_t > ( ) ;
} else {
config [ " lastModified " ] = 0ULL ;
}
if ( ! row [ 5 ] . is_null ( ) ) {
config [ " mtu " ] = row [ 5 ] . as < int > ( ) ;
} else {
config [ " mtu " ] = 2800 ;
}
if ( ! row [ 6 ] . is_null ( ) ) {
config [ " multicastLimit " ] = row [ 6 ] . as < int > ( ) ;
} else {
config [ " multicastLimit " ] = 64 ;
}
config [ " name " ] = row [ 7 ] . as < std : : string > ( ) ;
config [ " private " ] = row [ 8 ] . as < bool > ( ) ;
if ( ! row [ 9 ] . is_null ( ) ) {
config [ " remoteTraceLevel " ] = row [ 9 ] . as < int > ( ) ;
} else {
config [ " remoteTraceLevel " ] = 0 ;
}
if ( ! row [ 10 ] . is_null ( ) ) {
config [ " remoteTraceTarget " ] = row [ 10 ] . as < std : : string > ( ) ;
} else {
config [ " remoteTraceTarget " ] = nullptr ;
}
if ( ! row [ 11 ] . is_null ( ) ) {
config [ " revision " ] = row [ 11 ] . as < uint64_t > ( ) ;
} else {
config [ " revision " ] = 0ULL ;
//fprintf(stderr, "Error converting revision: %s\n", PQgetvalue(res, i, 11));
}
config [ " rules " ] = json : : parse ( row [ 12 ] . as < std : : string > ( ) ) ;
config [ " tags " ] = json : : parse ( row [ 13 ] . as < std : : string > ( ) ) ;
config [ " v4AssignMode " ] = json : : parse ( row [ 14 ] . as < std : : string > ( ) ) ;
config [ " v6AssignMode " ] = json : : parse ( row [ 15 ] . as < std : : string > ( ) ) ;
config [ " ssoEnabled " ] = row [ 16 ] . as < bool > ( ) ;
config [ " objtype " ] = " network " ;
config [ " ipAssignmentPools " ] = json : : array ( ) ;
config [ " routes " ] = json : : array ( ) ;
pqxx : : result r2 = w . exec_params ( " SELECT host(ip_range_start), host(ip_range_end) FROM ztc_network_assignment_pool WHERE network_id = $1 " , nwid ) ;
std : : string nwid = std : : get < 0 > ( row ) ;
std : : optional < int64_t > creationTime = std : : get < 1 > ( row ) ;
std : : optional < std : : string > capabilities = std : : get < 2 > ( row ) ;
std : : optional < bool > enableBroadcast = std : : get < 3 > ( row ) ;
std : : optional < uint64_t > lastModified = std : : get < 4 > ( row ) ;
std : : optional < int > mtu = std : : get < 5 > ( row ) ;
std : : optional < int > multicastLimit = std : : get < 6 > ( row ) ;
std : : optional < std : : string > name = std : : get < 7 > ( row ) ;
bool isPrivate = std : : get < 8 > ( row ) ;
std : : optional < int > remoteTraceLevel = std : : get < 9 > ( row ) ;
std : : optional < std : : string > remoteTraceTarget = std : : get < 10 > ( row ) ;
std : : optional < uint64_t > revision = std : : get < 11 > ( row ) ;
std : : optional < std : : string > rules = std : : get < 12 > ( row ) ;
std : : optional < std : : string > tags = std : : get < 13 > ( row ) ;
std : : optional < std : : string > v4AssignMode = std : : get < 14 > ( row ) ;
std : : optional < std : : string > v6AssignMode = std : : get < 15 > ( row ) ;
std : : optional < bool > ssoEnabled = std : : get < 16 > ( row ) ;
for ( auto row2 = r2 . begin ( ) ; row2 ! = r2 . end ( ) ; row2 + + ) {
json ip ;
ip [ " ipRangeStart " ] = row2 [ 0 ] . as < std : : string > ( ) ;
ip [ " ipRangeEnd " ] = row2 [ 1 ] . as < std : : string > ( ) ;
networkSet . insert ( nwid ) ;
config [ " id " ] = nwid ;
config [ " nwid " ] = nwid ;
config [ " creationTime " ] = creationTime . value_or ( 0 ) ;
config [ " capabilities " ] = json : : parse ( capabilities . value_or ( " [] " ) ) ;
config [ " enableBroadcast " ] = enableBroadcast . value_or ( false ) ;
config [ " lastModified " ] = lastModified . value_or ( 0 ) ;
config [ " mtu " ] = mtu . value_or ( 2800 ) ;
config [ " multicastLimit " ] = multicastLimit . value_or ( 64 ) ;
config [ " name " ] = name . value_or ( " " ) ;
config [ " private " ] = isPrivate ;
config [ " remoteTraceLevel " ] = remoteTraceLevel . value_or ( 0 ) ;
config [ " remoteTraceTarget " ] = remoteTraceTarget . value_or ( " " ) ;
config [ " revision " ] = revision . value_or ( 0 ) ;
config [ " rules " ] = json : : parse ( rules . value_or ( " [] " ) ) ;
config [ " tags " ] = json : : parse ( tags . value_or ( " [] " ) ) ;
config [ " v4AssignMode " ] = json : : parse ( v4AssignMode . value_or ( " {} " ) ) ;
config [ " v6AssignMode " ] = json : : parse ( v6AssignMode . value_or ( " {} " ) ) ;
config [ " ssoEnabled " ] = ssoEnabled . value_or ( false ) ;
config [ " objtype " ] = " network " ;
config [ " ipAssignmentPools " ] = json : : array ( ) ;
config [ " routes " ] = json : : array ( ) ;
config [ " ipAssignmentPools " ] . push_back ( ip ) ;
{
pqxx : : work w2 { * c2 - > c } ;
pqxx : : result r2 = w2 . exec_params ( " SELECT host(ip_range_start), host(ip_range_end) FROM ztc_network_assignment_pool WHERE network_id = $1 " , nwid ) ;
for ( auto row2 = r2 . begin ( ) ; row2 ! = r2 . end ( ) ; row2 + + ) {
json ip ;
ip [ " ipRangeStart " ] = row2 [ 0 ] . as < std : : string > ( ) ;
ip [ " ipRangeEnd " ] = row2 [ 1 ] . as < std : : string > ( ) ;
config [ " ipAssignmentPools " ] . push_back ( ip ) ;
}
w2 . commit ( ) ;
}
r2 = w . exec_params ( " SELECT host(address), bits, host(via) FROM ztc_network_route WHERE network_id = $1 " , nwid ) ;
for ( auto row2 = r2 . begin ( ) ; row2 ! = r2 . end ( ) ; row2 + + ) {
std : : string addr = row2 [ 0 ] . as < std : : string > ( ) ;
std : : string bits = row2 [ 1 ] . as < std : : string > ( ) ;
json route ;
route [ " target " ] = addr + " / " + bits ;
if ( row [ 2 ] . is_null ( ) ) {
route [ " via " ] = nullptr ;
} else {
route [ " via " ] = row [ 2 ] . as < std : : string > ( ) ;
{
pqxx : : work w2 { * c2 - > c } ;
pqxx : : result r2 = w2 . exec_params ( " SELECT host(address), bits, host(via) FROM ztc_network_route WHERE network_id = $1 " , nwid ) ;
for ( auto row2 = r2 . begin ( ) ; row2 ! = r2 . end ( ) ; row2 + + ) {
std : : string addr = row2 [ 0 ] . as < std : : string > ( ) ;
std : : string bits = row2 [ 1 ] . as < std : : string > ( ) ;
json route ;
route [ " target " ] = addr + " / " + bits ;
if ( row2 [ 2 ] . is_null ( ) ) {
route [ " via " ] = nullptr ;
} else {
route [ " via " ] = row2 [ 2 ] . as < std : : string > ( ) ;
}
config [ " routes " ] . push_back ( route ) ;
}
config [ " routes " ] . push_back ( route ) ;
w2 . commit ( ) ;
}
r2 = w . exec_params ( " SELECT domain, servers FROM ztc_network_dns WHERE network_id = $1 " , nwid ) ;
if ( r2 . size ( ) > 1 ) {
fprintf ( stderr , " ERROR: invalid number of DNS configurations for network %s. Must be 0 or 1 \n " , nwid . c_str ( ) ) ;
} else if ( r2 . size ( ) = = 1 ) {
auto dnsRow = r2 . begin ( ) ;
json obj ;
std : : string domain = dnsRow [ 0 ] . as < std : : string > ( ) ;
std : : string serverList = dnsRow [ 1 ] . as < std : : string > ( ) ;
auto servers = json : : array ( ) ;
if ( serverList . rfind ( " { " , 0 ) ! = std : : string : : npos ) {
serverList = serverList . substr ( 1 , serverList . size ( ) - 2 ) ;
std : : stringstream ss ( serverList ) ;
while ( ss . good ( ) ) {
std : : string server ;
std : : getline ( ss , server , ' , ' ) ;
servers . push_back ( server ) ;
{
pqxx : : work w2 { * c2 - > c } ;
pqxx : : result r2 = w2 . exec_params ( " SELECT domain, servers FROM ztc_network_dns WHERE network_id = $1 " , nwid ) ;
if ( r2 . size ( ) > 1 ) {
fprintf ( stderr , " ERROR: invalid number of DNS configurations for network %s. Must be 0 or 1 \n " , nwid . c_str ( ) ) ;
} else if ( r2 . size ( ) = = 1 ) {
auto dnsRow = r2 . begin ( ) ;
json obj ;
std : : string domain = dnsRow [ 0 ] . as < std : : string > ( ) ;
std : : string serverList = dnsRow [ 1 ] . as < std : : string > ( ) ;
auto servers = json : : array ( ) ;
if ( serverList . rfind ( " { " , 0 ) ! = std : : string : : npos ) {
serverList = serverList . substr ( 1 , serverList . size ( ) - 2 ) ;
std : : stringstream ss ( serverList ) ;
while ( ss . good ( ) ) {
std : : string server ;
std : : getline ( ss , server , ' , ' ) ;
servers . push_back ( server ) ;
}
}
obj [ " domain " ] = domain ;
obj [ " servers " ] = servers ;
config [ " dns " ] = obj ;
}
obj [ " domain " ] = domain ;
obj [ " servers " ] = servers ;
config [ " dns " ] = obj ;
w2 . commit ( ) ;
}
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 > ( ) ;
{
pqxx : : work w2 { * c2 - > c } ;
pqxx : : result r2 = w2 . 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 row2 = r2 . at ( 0 ) ;
config [ " clientId " ] = row2 [ 0 ] . as < std : : string > ( ) ;
config [ " authorizationEndpoint " ] = row2 [ 1 ] . as < std : : string > ( ) ;
}
w2 . commit ( ) ;
}
_networkChanged ( empty , config , false ) ;
_networkChanged ( empty , config , false ) ;
}
w . commit ( ) ;
_pool - > unborrow ( c2 ) ;
_pool - > unborrow ( c ) ;
if ( + + this - > _ready = = 2 ) {
@ -595,12 +614,10 @@ void PostgreSQL::initializeMembers()
std : : string networkId ;
try {
std : : unordered_map < std : : string , std : : string > networkMembers ;
fprintf ( stderr , " Initializing Members... \n " ) ;
auto c = _pool - > borrow ( ) ;
pqxx : : work w { * c - > c } ;
pqxx : : result r = w . exec_params (
" SELECT m.id, m.network_id, m.active_bridge, m.authorized, m.capabilities, (EXTRACT(EPOCH FROM m.creation_time AT TIME ZONE 'UTC')*1000)::bigint, m.identity, "
char qbuf [ 2048 ] ;
sprintf ( qbuf , " SELECT m.id, m.network_id, m.active_bridge, m.authorized, m.capabilities, (EXTRACT(EPOCH FROM m.creation_time AT TIME ZONE 'UTC')*1000)::bigint, m.identity, "
" (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, "
" m.remote_trace_level, m.remote_trace_target, m.tags, m.v_major, m.v_minor, m.v_rev, m.v_proto, "
@ -608,137 +625,132 @@ void PostgreSQL::initializeMembers()
" FROM ztc_member m "
" INNER JOIN ztc_network n "
" ON n.id = m.network_id "
" WHERE n.controller_id = $1 AND m.deleted = false " , _myAddressStr ) ;
for ( auto row = r . begin ( ) ; row ! = r . end ( ) ; row + + ) {
" WHERE n.controller_id = '%s' AND m.deleted = false " , _myAddressStr . c_str ( ) ) ;
auto c = _pool - > borrow ( ) ;
auto c2 = _pool - > borrow ( ) ;
pqxx : : work w { * c - > c } ;
auto stream = pqxx : : stream_from : : query ( w , qbuf ) ;
std : : tuple <
std : : string // memberId
, std : : string // memberId
, std : : optional < bool > // activeBridge
, std : : optional < bool > // authorized
, std : : optional < std : : string > // capabilities
, std : : optional < uint64_t > // creationTime
, std : : optional < std : : string > // identity
, std : : optional < uint64_t > // lastAuthorizedTime
, std : : optional < uint64_t > // lastDeauthorizedTime
, std : : optional < int > // remoteTraceLevel
, std : : optional < std : : string > // remoteTraceTarget
, std : : optional < std : : string > // tags
, std : : optional < int > // vMajor
, std : : optional < int > // vMinor
, std : : optional < int > // vRev
, std : : optional < int > // vProto
, std : : optional < bool > // noAutoAssignIps
, std : : optional < uint64_t > // revision
, std : : optional < bool > // ssoExempt
> row ;
while ( stream > > row ) {
json empty ;
json config ;
memberId = " " ;
networkId = " " ;
initMember ( config ) ;
if ( row [ 0 ] . is_null ( ) ) {
fprintf ( stderr , " Null memberID?!? \n " ) ;
continue ;
}
if ( row [ 1 ] . is_null ( ) ) {
fprintf ( stderr , " Null NetworkID?!? \n " ) ;
}
memberId = row [ 0 ] . as < std : : string > ( ) ;
networkId = row [ 1 ] . as < std : : string > ( ) ;
memberId = std : : get < 0 > ( row ) ;
networkId = std : : get < 1 > ( row ) ;
std : : optional < bool > activeBridge = std : : get < 2 > ( row ) ;
std : : optional < bool > authorized = std : : get < 3 > ( row ) ;
std : : optional < std : : string > capabilities = std : : get < 4 > ( row ) ;
std : : optional < uint64_t > creationTime = std : : get < 5 > ( row ) ;
std : : optional < std : : string > identity = std : : get < 6 > ( row ) ;
std : : optional < uint64_t > lastAuthorizedTime = std : : get < 7 > ( row ) ;
std : : optional < uint64_t > lastDeauthorizedTime = std : : get < 8 > ( row ) ;
std : : optional < int > remoteTraceLevel = std : : get < 9 > ( row ) ;
std : : optional < std : : string > remoteTraceTarget = std : : get < 10 > ( row ) ;
std : : optional < std : : string > tags = std : : get < 11 > ( row ) ;
std : : optional < int > vMajor = std : : get < 12 > ( row ) ;
std : : optional < int > vMinor = std : : get < 13 > ( row ) ;
std : : optional < int > vRev = std : : get < 14 > ( row ) ;
std : : optional < int > vProto = std : : get < 15 > ( row ) ;
std : : optional < bool > noAutoAssignIps = std : : get < 16 > ( row ) ;
std : : optional < uint64_t > revision = std : : get < 17 > ( row ) ;
std : : optional < bool > ssoExempt = std : : get < 18 > ( row ) ;
config [ " id " ] = memberId ;
config [ " nwid " ] = networkId ;
config [ " activeBridge " ] = row [ 2 ] . as < bool > ( ) ;
config [ " authorized " ] = row [ 3 ] . as < bool > ( ) ;
if ( row [ 4 ] . is_null ( ) ) {
config [ " capabilities " ] = json : : array ( ) ;
} else {
try {
config [ " capabilities " ] = json : : parse ( row [ 4 ] . as < std : : string > ( ) ) ;
} catch ( std : : exception & e ) {
config [ " capabilities " ] = json : : array ( ) ;
}
}
config [ " creationTime " ] = row [ 5 ] . as < uint64_t > ( ) ;
config [ " identity " ] = row [ 6 ] . as < std : : string > ( ) ;
if ( ! row [ 7 ] . is_null ( ) ) {
config [ " lastAuthorizedTime " ] = row [ 7 ] . as < uint64_t > ( ) ;
} else {
config [ " lastAuthorizedTime " ] = 0ULL ;
//fprintf(stderr, "Error updating last auth time (member): %s\n", PQgetvalue(res, i, 7));
}
if ( ! row [ 8 ] . is_null ( ) ) {
config [ " lastDeauthorizedTime " ] = row [ 8 ] . as < uint64_t > ( ) ;
} else {
config [ " lastDeauthorizedTime " ] = 0ULL ;
//fprintf(stderr, "Error updating last deauth time (member): %s\n", PQgetvalue(res, i, 8));
}
if ( ! row [ 9 ] . is_null ( ) ) {
config [ " remoteTraceLevel " ] = row [ 9 ] . as < int > ( ) ;
} else {
config [ " remoteTraceLevel " ] = 0 ;
}
if ( ! row [ 10 ] . is_null ( ) ) {
config [ " remoteTraceTarget " ] = row [ 10 ] . as < std : : string > ( ) ;
} else {
config [ " remoteTraceTarget " ] = " " ;
}
if ( row [ 11 ] . is_null ( ) ) {
config [ " tags " ] = json : : array ( ) ;
} else {
try {
config [ " tags " ] = json : : parse ( row [ 11 ] . as < std : : string > ( ) ) ;
} catch ( std : : exception & e ) {
config [ " tags " ] = json : : array ( ) ;
config [ " activeBridge " ] = activeBridge . value_or ( false ) ;
config [ " authorized " ] = authorized . value_or ( false ) ;
config [ " capabilities " ] = json : : parse ( capabilities . value_or ( " [] " ) ) ;
config [ " creationTime " ] = creationTime . value_or ( 0 ) ;
config [ " identity " ] = identity . value_or ( " " ) ;
config [ " lastAuthorizedTime " ] = lastAuthorizedTime . value_or ( 0 ) ;
config [ " lastDeauthorizedTime " ] = lastDeauthorizedTime . value_or ( 0 ) ;
config [ " remoteTraceLevel " ] = remoteTraceLevel . value_or ( 0 ) ;
config [ " remoteTraceTarget " ] = remoteTraceTarget . value_or ( " " ) ;
config [ " tags " ] = json : : parse ( tags . value_or ( " [] " ) ) ;
config [ " vMajor " ] = vMajor . value_or ( - 1 ) ;
config [ " vMinor " ] = vMinor . value_or ( - 1 ) ;
config [ " vRev " ] = vRev . value_or ( - 1 ) ;
config [ " vProto " ] = vProto . value_or ( - 1 ) ;
config [ " noAutoAssignIps " ] = noAutoAssignIps . value_or ( false ) ;
config [ " revision " ] = revision . value_or ( 0 ) ;
config [ " ssoExempt " ] = ssoExempt . value_or ( false ) ;
{
config [ " authenticationExpiryTime " ] = 0LL ;
pqxx : : work w2 { * c2 - > c } ;
pqxx : : result authRes = w2 . 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 AND e.authentication_expiry_time IS NOT NULL "
" ORDER BY e.authentication_expiry_time DESC LIMIT 1 " , networkId , memberId ) ;
if ( authRes . size ( ) = = 1 & & ! authRes . at ( 0 ) [ 0 ] . is_null ( ) ) {
// there is an expiry time record
config [ " authenticationExpiryTime " ] = authRes . at ( 0 ) [ 0 ] . as < int64_t > ( ) ;
} else {
config [ " authenticationExpiryTime " ] = 0 ;
}
}
if ( ! row [ 12 ] . is_null ( ) ) {
config [ " vMajor " ] = row [ 12 ] . as < int > ( ) ;
} else {
config [ " vMajor " ] = - 1 ;
}
if ( ! row [ 13 ] . is_null ( ) ) {
config [ " vMinor " ] = row [ 13 ] . as < int > ( ) ;
} else {
config [ " vMinor " ] = - 1 ;
}
if ( ! row [ 14 ] . is_null ( ) ) {
config [ " vRev " ] = row [ 14 ] . as < int > ( ) ;
} else {
config [ " vRev " ] = - 1 ;
}
if ( ! row [ 15 ] . is_null ( ) ) {
config [ " vProto " ] = row [ 15 ] . as < int > ( ) ;
} else {
config [ " vProto " ] = - 1 ;
}
config [ " noAutoAssignIps " ] = row [ 16 ] . as < bool > ( ) ;
if ( ! row [ 17 ] . is_null ( ) ) {
config [ " revision " ] = row [ 17 ] . as < uint64_t > ( ) ;
} else {
config [ " revision " ] = 0ULL ;
}
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 AND e.authentication_expiry_time IS NOT NULL "
" ORDER BY e.authentication_expiry_time DESC LIMIT 1 " , networkId , memberId ) ;
if ( authRes . size ( ) = = 1 & & ! authRes . at ( 0 ) [ 0 ] . is_null ( ) ) {
// there is an expiry time record
config [ " authenticationExpiryTime " ] = authRes . at ( 0 ) [ 0 ] . as < int64_t > ( ) ;
} else {
config [ " authenticationExpiryTime " ] = 0 ;
w2 . commit ( ) ;
}
config [ " objtype " ] = " member " ;
config [ " ipAssignments " ] = json : : array ( ) ;
pqxx : : result r2 = w . exec_params ( " SELECT DISTINCT address "
" FROM ztc_member_ip_assignment "
" WHERE member_id = $1 AND network_id = $2 " , memberId , networkId ) ;
for ( auto row2 = r2 . begin ( ) ; row2 ! = r2 . end ( ) ; row2 + + ) {
std : : string ipaddr = row2 [ 0 ] . as < std : : string > ( ) ;
std : : size_t pos = ipaddr . find ( ' / ' ) ;
if ( pos ! = std : : string : : npos ) {
ipaddr = ipaddr . substr ( 0 , pos ) ;
{
config [ " ipAssignments " ] = json : : array ( ) ;
pqxx : : work w2 { * c2 - > c } ;
pqxx : : result r2 = w2 . exec_params ( " SELECT DISTINCT address "
" FROM ztc_member_ip_assignment "
" WHERE member_id = $1 AND network_id = $2 " , memberId , networkId ) ;
for ( auto row2 = r2 . begin ( ) ; row2 ! = r2 . end ( ) ; row2 + + ) {
std : : string ipaddr = row2 [ 0 ] . as < std : : string > ( ) ;
std : : size_t pos = ipaddr . find ( ' / ' ) ;
if ( pos ! = std : : string : : npos ) {
ipaddr = ipaddr . substr ( 0 , pos ) ;
}
config [ " ipAssignments " ] . push_back ( ipaddr ) ;
}
config [ " ipAssignments " ] . push_back ( ipaddr ) ;
w2 . commit ( ) ;
}
_memberChanged ( empty , config , false ) ;
memberId = " " ;
networkId = " " ;
}
w . commit ( ) ;
_pool - > unborrow ( c2 ) ;
_pool - > unborrow ( c ) ;
if ( + + this - > _ready = = 2 ) {
@ -1313,7 +1325,7 @@ void PostgreSQL::onlineNotification_Postgres()
// using pqxx::stream_to would be a really nice alternative here, but
// unfortunately it doesn't support upserts.
fprintf ( stderr , " online notification tick \n " ) ;
// fprintf(stderr, "online notification tick\n");
std : : stringstream memberUpdate ;
memberUpdate < < " INSERT INTO ztc_member_status (network_id, member_id, address, last_updated) VALUES " ;
bool firstRun = true ;
@ -1375,7 +1387,7 @@ void PostgreSQL::onlineNotification_Postgres()
pqxx : : result res = w . exec0 ( memberUpdate . str ( ) ) ;
w . commit ( ) ;
}
fprintf ( stderr , " Updated online status of %d members \n " , updateCount ) ;
// fprintf(stderr, "Updated online status of %d members\n", updateCount);
_pool - > unborrow ( c ) ;
} catch ( std : : exception & e ) {
fprintf ( stderr , " %s: error in onlinenotification thread: %s \n " , _myAddressStr . c_str ( ) , e . what ( ) ) ;