Add peer login expiration (#682)

This PR adds a peer login expiration logic that requires
peers created by a user to re-authenticate (re-login) after
a certain threshold of time (24h by default).

The Account object now has a PeerLoginExpiration
property that indicates the duration after which a peer's
login will expire and a login will be required. Defaults to 24h.

There are two new properties added to the Peer object:
LastLogin that indicates the last time peer successfully used
the Login gRPC endpoint and LoginExpirationEnabled that
enables/disables peer login expiration.

The login expiration logic applies only to peers that were created
by a user and not those that were added with a setup key.
This commit is contained in:
Misha Bragin
2023-02-13 06:21:02 -05:00
committed by GitHub
parent aecee361d0
commit 3fc89749c1
6 changed files with 226 additions and 53 deletions

View File

@@ -26,11 +26,12 @@ import (
)
const (
PublicCategory = "public"
PrivateCategory = "private"
UnknownCategory = "unknown"
CacheExpirationMax = 7 * 24 * 3600 * time.Second // 7 days
CacheExpirationMin = 3 * 24 * 3600 * time.Second // 3 days
PublicCategory = "public"
PrivateCategory = "private"
UnknownCategory = "unknown"
CacheExpirationMax = 7 * 24 * 3600 * time.Second // 7 days
CacheExpirationMin = 3 * 24 * 3600 * time.Second // 3 days
DefaultPeerLoginExpiration = 24 * time.Hour
)
func cacheEntryExpiration() time.Duration {
@@ -48,6 +49,7 @@ type AccountManager interface {
SaveUser(accountID, userID string, update *User) (*UserInfo, error)
GetSetupKey(accountID, userID, keyID string) (*SetupKey, error)
GetAccountByUserOrAccountID(userID, accountID, domain string) (*Account, error)
GetAccountByPeerID(peerID string) (*Account, error)
GetAccountFromToken(claims jwtclaims.AuthorizationClaims) (*Account, *User, error)
IsUserAdmin(claims jwtclaims.AuthorizationClaims) (bool, error)
AccountExists(accountId string) (*bool, error)
@@ -93,6 +95,7 @@ type AccountManager interface {
GetDNSSettings(accountID string, userID string) (*DNSSettings, error)
SaveDNSSettings(accountID string, userID string, dnsSettingsToSave *DNSSettings) error
GetPeer(accountID, peerID, userID string) (*Peer, error)
UpdatePeerLastLogin(peerID string) error
}
type DefaultAccountManager struct {
@@ -134,6 +137,9 @@ type Account struct {
Routes map[string]*route.Route
NameServerGroups map[string]*nbdns.NameServerGroup
DNSSettings *DNSSettings
// PeerLoginExpiration is a setting that indicates when peer login expires.
// Applies to all peers that have Peer.LoginExpirationEnabled set to true.
PeerLoginExpiration time.Duration
}
type UserInfo struct {
@@ -484,6 +490,7 @@ func (a *Account) Copy() *Account {
Routes: routes,
NameServerGroups: nsGroups,
DNSSettings: dnsSettings,
PeerLoginExpiration: a.PeerLoginExpiration,
}
}
@@ -606,6 +613,11 @@ func (am *DefaultAccountManager) warmupIDPCache() error {
return nil
}
// GetAccountByPeerID returns account from the store by a provided peer ID
func (am *DefaultAccountManager) GetAccountByPeerID(peerID string) (*Account, error) {
return am.Store.GetAccountByPeerID(peerID)
}
// GetAccountByUserOrAccountID looks for an account by user or accountID, if no account is provided and
// userID doesn't have an account associated with it, one account is created
func (am *DefaultAccountManager) GetAccountByUserOrAccountID(userID, accountID, domain string) (*Account, error) {
@@ -1085,16 +1097,17 @@ func newAccountWithId(accountId, userId, domain string) *Account {
log.Debugf("created new account %s with setup key %s", accountId, defaultKey.Key)
acc := &Account{
Id: accountId,
SetupKeys: setupKeys,
Network: network,
Peers: peers,
Users: users,
CreatedBy: userId,
Domain: domain,
Routes: routes,
NameServerGroups: nameServersGroups,
DNSSettings: dnsSettings,
Id: accountId,
SetupKeys: setupKeys,
Network: network,
Peers: peers,
Users: users,
CreatedBy: userId,
Domain: domain,
Routes: routes,
NameServerGroups: nameServersGroups,
DNSSettings: dnsSettings,
PeerLoginExpiration: DefaultPeerLoginExpiration,
}
addAllGroup(acc)