mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-28 23:39:07 +01:00
[management] expire and disconnect peers while including offline peers (#7467)
This commit is contained in:
+61
-16
@@ -1177,28 +1177,35 @@ func (am *DefaultAccountManager) expireAndUpdatePeers(ctx context.Context, accou
|
||||
dnsDomain := am.networkMapController.GetDNSDomain(settings)
|
||||
|
||||
var peerIDs []string
|
||||
for _, peer := range peers {
|
||||
defer func() {
|
||||
if len(peerIDs) == 0 {
|
||||
return
|
||||
}
|
||||
// this will trigger peer disconnect from the management service
|
||||
log.Debugf("Expiring %d peers for account %s", len(peerIDs), accountID)
|
||||
am.networkMapController.DisconnectPeers(ctx, accountID, peerIDs)
|
||||
}()
|
||||
for _, candidate := range peers {
|
||||
// nolint:staticcheck
|
||||
ctx = context.WithValue(ctx, nbcontext.PeerIDKey, peer.Key)
|
||||
peerCtx := context.WithValue(ctx, nbcontext.PeerIDKey, candidate.Key)
|
||||
|
||||
if peer.UserID == "" {
|
||||
if candidate.UserID == "" {
|
||||
// we do not want to expire peers that are added via setup key
|
||||
continue
|
||||
}
|
||||
|
||||
if peer.Status.LoginExpired {
|
||||
peer, err := am.expirePeerIfStillDue(peerCtx, accountID, candidate.ID, settings, reason)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if peer == nil {
|
||||
continue
|
||||
}
|
||||
peerIDs = append(peerIDs, peer.ID)
|
||||
peer.MarkLoginExpired(true)
|
||||
|
||||
if err := am.Store.SavePeerStatus(ctx, accountID, peer.ID, *peer.Status); err != nil {
|
||||
return err
|
||||
}
|
||||
meta := peer.EventMeta(dnsDomain)
|
||||
meta["reason"] = string(reason)
|
||||
am.StoreEvent(
|
||||
ctx,
|
||||
peerCtx,
|
||||
peer.UserID, peer.ID, accountID,
|
||||
activity.PeerLoginExpired, meta,
|
||||
)
|
||||
@@ -1215,15 +1222,53 @@ func (am *DefaultAccountManager) expireAndUpdatePeers(ctx context.Context, accou
|
||||
if err != nil {
|
||||
return fmt.Errorf("notify network map controller of peer update: %w", err)
|
||||
}
|
||||
|
||||
if len(peerIDs) != 0 {
|
||||
// this will trigger peer disconnect from the management service
|
||||
log.Debugf("Expiring %d peers for account %s", len(peerIDs), accountID)
|
||||
am.networkMapController.DisconnectPeers(ctx, accountID, peerIDs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// expirePeerIfStillDue flags the peer as login-expired and returns its fresh copy, or nil
|
||||
// when it no longer qualifies. The candidate list is read without a lock, so a login that
|
||||
// landed in between would otherwise be overwritten with a stale expired status.
|
||||
func (am *DefaultAccountManager) expirePeerIfStillDue(ctx context.Context, accountID, peerID string, settings *types.Settings, reason peerExpirationReason) (*nbpeer.Peer, error) {
|
||||
var expired *nbpeer.Peer
|
||||
err := am.Store.ExecuteInTransaction(ctx, func(transaction store.Store) error {
|
||||
peer, err := transaction.GetPeerByID(ctx, store.LockingStrengthUpdate, accountID, peerID)
|
||||
if err != nil {
|
||||
if s, ok := status.FromError(err); ok && s.Type() == status.NotFound {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if peer.Status.LoginExpired || !peerExpirationDue(peer, settings, reason) {
|
||||
return nil
|
||||
}
|
||||
peer.MarkLoginExpired(true)
|
||||
if err := transaction.SavePeerStatus(ctx, accountID, peer.ID, *peer.Status); err != nil {
|
||||
return err
|
||||
}
|
||||
expired = peer
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return expired, nil
|
||||
}
|
||||
|
||||
// peerExpirationDue re-evaluates a time-based expiry against the peer's current state.
|
||||
// Administrative reasons expire the peer unconditionally.
|
||||
func peerExpirationDue(peer *nbpeer.Peer, settings *types.Settings, reason peerExpirationReason) bool {
|
||||
switch reason {
|
||||
case peerExpirationSessionExpired:
|
||||
expired, _ := peer.LoginExpired(settings.PeerLoginExpiration)
|
||||
return settings.PeerLoginExpirationEnabled && expired
|
||||
case peerExpirationInactivity:
|
||||
expired, _ := peer.SessionExpired(settings.PeerInactivityExpiration)
|
||||
return settings.PeerInactivityExpirationEnabled && expired
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (am *DefaultAccountManager) deleteUserFromIDP(ctx context.Context, targetUserID, accountID string) error {
|
||||
if am.userDeleteFromIDPEnabled {
|
||||
log.WithContext(ctx).Debugf("user %s deleted from IdP", targetUserID)
|
||||
|
||||
Reference in New Issue
Block a user