mirror of
https://github.com/netbirdio/netbird.git
synced 2025-06-21 02:08:40 +02:00
Add login expiration fields to peer HTTP API (#687)
Return login expiration related fields in the Peer HTTP GET endpoint. Support enable/disable peer's login expiration via HTTP PUT.
This commit is contained in:
parent
b64f5ffcb4
commit
756ce96da9
@ -61,6 +61,10 @@ const (
|
|||||||
PeerSSHDisabled
|
PeerSSHDisabled
|
||||||
// PeerRenamed indicates that a user renamed a peer
|
// PeerRenamed indicates that a user renamed a peer
|
||||||
PeerRenamed
|
PeerRenamed
|
||||||
|
// PeerLoginExpirationEnabled indicates that a user enabled login expiration of a peer
|
||||||
|
PeerLoginExpirationEnabled
|
||||||
|
// PeerLoginExpirationDisabled indicates that a user disabled login expiration of a peer
|
||||||
|
PeerLoginExpirationDisabled
|
||||||
// NameserverGroupCreated indicates that a user created a nameservers group
|
// NameserverGroupCreated indicates that a user created a nameservers group
|
||||||
NameserverGroupCreated
|
NameserverGroupCreated
|
||||||
// NameserverGroupDeleted indicates that a user deleted a nameservers group
|
// NameserverGroupDeleted indicates that a user deleted a nameservers group
|
||||||
@ -130,6 +134,10 @@ const (
|
|||||||
PeerSSHDisabledMessage string = "Peer SSH server disabled"
|
PeerSSHDisabledMessage string = "Peer SSH server disabled"
|
||||||
// PeerRenamedMessage is a human-readable text message of the PeerRenamed activity
|
// PeerRenamedMessage is a human-readable text message of the PeerRenamed activity
|
||||||
PeerRenamedMessage string = "Peer renamed"
|
PeerRenamedMessage string = "Peer renamed"
|
||||||
|
// PeerLoginExpirationDisabledMessage is a human-readable text message of the PeerLoginExpirationDisabled activity
|
||||||
|
PeerLoginExpirationDisabledMessage string = "Peer login expiration disabled"
|
||||||
|
// PeerLoginExpirationEnabledMessage is a human-readable text message of the PeerLoginExpirationEnabled activity
|
||||||
|
PeerLoginExpirationEnabledMessage string = "Peer login expiration enabled"
|
||||||
// NameserverGroupCreatedMessage is a human-readable text message of the NameserverGroupCreated activity
|
// NameserverGroupCreatedMessage is a human-readable text message of the NameserverGroupCreated activity
|
||||||
NameserverGroupCreatedMessage string = "Nameserver group created"
|
NameserverGroupCreatedMessage string = "Nameserver group created"
|
||||||
// NameserverGroupDeletedMessage is a human-readable text message of the NameserverGroupDeleted activity
|
// NameserverGroupDeletedMessage is a human-readable text message of the NameserverGroupDeleted activity
|
||||||
@ -202,6 +210,10 @@ func (a Activity) Message() string {
|
|||||||
return PeerSSHEnabledMessage
|
return PeerSSHEnabledMessage
|
||||||
case PeerSSHDisabled:
|
case PeerSSHDisabled:
|
||||||
return PeerSSHDisabledMessage
|
return PeerSSHDisabledMessage
|
||||||
|
case PeerLoginExpirationEnabled:
|
||||||
|
return PeerLoginExpirationEnabledMessage
|
||||||
|
case PeerLoginExpirationDisabled:
|
||||||
|
return PeerLoginExpirationDisabledMessage
|
||||||
case PeerRenamed:
|
case PeerRenamed:
|
||||||
return PeerRenamedMessage
|
return PeerRenamedMessage
|
||||||
case NameserverGroupCreated:
|
case NameserverGroupCreated:
|
||||||
@ -278,6 +290,10 @@ func (a Activity) StringCode() string {
|
|||||||
return "peer.ssh.enable"
|
return "peer.ssh.enable"
|
||||||
case PeerSSHDisabled:
|
case PeerSSHDisabled:
|
||||||
return "peer.ssh.disable"
|
return "peer.ssh.disable"
|
||||||
|
case PeerLoginExpirationDisabled:
|
||||||
|
return "peer.login.expiration.disable"
|
||||||
|
case PeerLoginExpirationEnabled:
|
||||||
|
return "peer.login.expiration.enable"
|
||||||
case NameserverGroupCreated:
|
case NameserverGroupCreated:
|
||||||
return "nameserver.group.add"
|
return "nameserver.group.add"
|
||||||
case NameserverGroupDeleted:
|
case NameserverGroupDeleted:
|
||||||
|
@ -145,6 +145,16 @@ components:
|
|||||||
dns_label:
|
dns_label:
|
||||||
description: Peer's DNS label is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's domain to the peer label. e.g. peer-dns-label.netbird.cloud
|
description: Peer's DNS label is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's domain to the peer label. e.g. peer-dns-label.netbird.cloud
|
||||||
type: string
|
type: string
|
||||||
|
login_expiration_enabled:
|
||||||
|
description: Indicates whether peer login expiration has been enabled or not
|
||||||
|
type: boolean
|
||||||
|
login_expired:
|
||||||
|
description: Indicates whether peer's login expired or not
|
||||||
|
type: boolean
|
||||||
|
last_login:
|
||||||
|
description: Last time this peer performed log in (authentication). E.g., user authenticated.
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
required:
|
required:
|
||||||
- ip
|
- ip
|
||||||
- connected
|
- connected
|
||||||
@ -155,6 +165,9 @@ components:
|
|||||||
- ssh_enabled
|
- ssh_enabled
|
||||||
- hostname
|
- hostname
|
||||||
- dns_label
|
- dns_label
|
||||||
|
- login_expiration_enabled
|
||||||
|
- login_expired
|
||||||
|
- last_login
|
||||||
SetupKey:
|
SetupKey:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -542,7 +555,7 @@ components:
|
|||||||
"account.create", "dns.setting.disabled.management.group.delete",
|
"account.create", "dns.setting.disabled.management.group.delete",
|
||||||
"route.add", "route.delete", "route.update",
|
"route.add", "route.delete", "route.update",
|
||||||
"nameserver.group.add", "nameserver.group.delete", "nameserver.group.update",
|
"nameserver.group.add", "nameserver.group.delete", "nameserver.group.update",
|
||||||
"peer.ssh.disable", "peer.ssh.enable", "peer.rename"
|
"peer.ssh.disable", "peer.ssh.enable", "peer.rename", "peer.login.expiration.disable", "peer.login.expiration.enable"
|
||||||
]
|
]
|
||||||
initiator_id:
|
initiator_id:
|
||||||
description: The ID of the initiator of the event. E.g., an ID of a user that triggered the event.
|
description: The ID of the initiator of the event. E.g., an ID of a user that triggered the event.
|
||||||
@ -741,7 +754,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
description: The Peer ID
|
description: The Peer ID
|
||||||
requestBody:
|
requestBody:
|
||||||
description: update to peers
|
description: update a peer
|
||||||
content:
|
content:
|
||||||
'application/json':
|
'application/json':
|
||||||
schema:
|
schema:
|
||||||
@ -751,9 +764,12 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
ssh_enabled:
|
ssh_enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
login_expiration_enabled:
|
||||||
|
type: boolean
|
||||||
required:
|
required:
|
||||||
- name
|
- name
|
||||||
- ssh_enabled
|
- ssh_enabled
|
||||||
|
- login_expiration_enabled
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: A Peer object
|
description: A Peer object
|
||||||
|
@ -21,6 +21,8 @@ const (
|
|||||||
EventActivityCodeNameserverGroupAdd EventActivityCode = "nameserver.group.add"
|
EventActivityCodeNameserverGroupAdd EventActivityCode = "nameserver.group.add"
|
||||||
EventActivityCodeNameserverGroupDelete EventActivityCode = "nameserver.group.delete"
|
EventActivityCodeNameserverGroupDelete EventActivityCode = "nameserver.group.delete"
|
||||||
EventActivityCodeNameserverGroupUpdate EventActivityCode = "nameserver.group.update"
|
EventActivityCodeNameserverGroupUpdate EventActivityCode = "nameserver.group.update"
|
||||||
|
EventActivityCodePeerLoginExpirationDisable EventActivityCode = "peer.login.expiration.disable"
|
||||||
|
EventActivityCodePeerLoginExpirationEnable EventActivityCode = "peer.login.expiration.enable"
|
||||||
EventActivityCodePeerRename EventActivityCode = "peer.rename"
|
EventActivityCodePeerRename EventActivityCode = "peer.rename"
|
||||||
EventActivityCodePeerSshDisable EventActivityCode = "peer.ssh.disable"
|
EventActivityCodePeerSshDisable EventActivityCode = "peer.ssh.disable"
|
||||||
EventActivityCodePeerSshEnable EventActivityCode = "peer.ssh.enable"
|
EventActivityCodePeerSshEnable EventActivityCode = "peer.ssh.enable"
|
||||||
@ -326,9 +328,18 @@ type Peer struct {
|
|||||||
// Ip Peer's IP address
|
// Ip Peer's IP address
|
||||||
Ip string `json:"ip"`
|
Ip string `json:"ip"`
|
||||||
|
|
||||||
|
// LastLogin Last time this peer performed log in (authentication). E.g., user authenticated.
|
||||||
|
LastLogin time.Time `json:"last_login"`
|
||||||
|
|
||||||
// LastSeen Last time peer connected to Netbird's management service
|
// LastSeen Last time peer connected to Netbird's management service
|
||||||
LastSeen time.Time `json:"last_seen"`
|
LastSeen time.Time `json:"last_seen"`
|
||||||
|
|
||||||
|
// LoginExpirationEnabled Indicates whether peer login expiration has been enabled or not
|
||||||
|
LoginExpirationEnabled bool `json:"login_expiration_enabled"`
|
||||||
|
|
||||||
|
// LoginExpired Indicates whether peer's login expired or not
|
||||||
|
LoginExpired bool `json:"login_expired"`
|
||||||
|
|
||||||
// Name Peer's hostname
|
// Name Peer's hostname
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
@ -626,8 +637,9 @@ type PutApiGroupsIdJSONBody struct {
|
|||||||
|
|
||||||
// PutApiPeersIdJSONBody defines parameters for PutApiPeersId.
|
// PutApiPeersIdJSONBody defines parameters for PutApiPeersId.
|
||||||
type PutApiPeersIdJSONBody struct {
|
type PutApiPeersIdJSONBody struct {
|
||||||
Name string `json:"name"`
|
LoginExpirationEnabled bool `json:"login_expiration_enabled"`
|
||||||
SshEnabled bool `json:"ssh_enabled"`
|
Name string `json:"name"`
|
||||||
|
SshEnabled bool `json:"ssh_enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PatchApiRoutesIdJSONBody defines parameters for PatchApiRoutesId.
|
// PatchApiRoutesIdJSONBody defines parameters for PatchApiRoutesId.
|
||||||
|
@ -47,7 +47,8 @@ func (h *Peers) updatePeer(account *server.Account, user *server.User, peerID st
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
update := &server.Peer{ID: peerID, SSHEnabled: req.SshEnabled, Name: req.Name}
|
update := &server.Peer{ID: peerID, SSHEnabled: req.SshEnabled, Name: req.Name,
|
||||||
|
LoginExpirationEnabled: req.LoginExpirationEnabled}
|
||||||
peer, err := h.accountManager.UpdatePeer(account.Id, user.Id, update)
|
peer, err := h.accountManager.UpdatePeer(account.Id, user.Id, update)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(err, w)
|
util.WriteError(err, w)
|
||||||
@ -150,19 +151,25 @@ func toPeerResponse(peer *server.Peer, account *server.Account, dnsDomain string
|
|||||||
if fqdn == "" {
|
if fqdn == "" {
|
||||||
fqdn = peer.DNSLabel
|
fqdn = peer.DNSLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expired, _ := peer.LoginExpired(account.Settings)
|
||||||
|
|
||||||
return &api.Peer{
|
return &api.Peer{
|
||||||
Id: peer.ID,
|
Id: peer.ID,
|
||||||
Name: peer.Name,
|
Name: peer.Name,
|
||||||
Ip: peer.IP.String(),
|
Ip: peer.IP.String(),
|
||||||
Connected: peer.Status.Connected,
|
Connected: peer.Status.Connected,
|
||||||
LastSeen: peer.Status.LastSeen,
|
LastSeen: peer.Status.LastSeen,
|
||||||
Os: fmt.Sprintf("%s %s", peer.Meta.OS, peer.Meta.Core),
|
Os: fmt.Sprintf("%s %s", peer.Meta.OS, peer.Meta.Core),
|
||||||
Version: peer.Meta.WtVersion,
|
Version: peer.Meta.WtVersion,
|
||||||
Groups: groupsInfo,
|
Groups: groupsInfo,
|
||||||
SshEnabled: peer.SSHEnabled,
|
SshEnabled: peer.SSHEnabled,
|
||||||
Hostname: peer.Meta.Hostname,
|
Hostname: peer.Meta.Hostname,
|
||||||
UserId: &peer.UserID,
|
UserId: &peer.UserID,
|
||||||
UiVersion: &peer.Meta.UIVersion,
|
UiVersion: &peer.Meta.UIVersion,
|
||||||
DnsLabel: fqdn,
|
DnsLabel: fqdn,
|
||||||
|
LoginExpirationEnabled: peer.LoginExpirationEnabled,
|
||||||
|
LastLogin: peer.LastLogin,
|
||||||
|
LoginExpired: expired,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"io"
|
"io"
|
||||||
@ -8,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/server/http/api"
|
"github.com/netbirdio/netbird/management/server/http/api"
|
||||||
|
|
||||||
@ -23,6 +25,13 @@ const testPeerID = "test_peer"
|
|||||||
func initTestMetaData(peers ...*server.Peer) *Peers {
|
func initTestMetaData(peers ...*server.Peer) *Peers {
|
||||||
return &Peers{
|
return &Peers{
|
||||||
accountManager: &mock_server.MockAccountManager{
|
accountManager: &mock_server.MockAccountManager{
|
||||||
|
UpdatePeerFunc: func(accountID, userID string, update *server.Peer) (*server.Peer, error) {
|
||||||
|
p := peers[0].Copy()
|
||||||
|
p.SSHEnabled = update.SSHEnabled
|
||||||
|
p.LoginExpirationEnabled = update.LoginExpirationEnabled
|
||||||
|
p.Name = update.Name
|
||||||
|
return p, nil
|
||||||
|
},
|
||||||
GetPeerFunc: func(accountID, peerID, userID string) (*server.Peer, error) {
|
GetPeerFunc: func(accountID, peerID, userID string) (*server.Peer, error) {
|
||||||
return peers[0], nil
|
return peers[0], nil
|
||||||
},
|
},
|
||||||
@ -40,6 +49,10 @@ func initTestMetaData(peers ...*server.Peer) *Peers {
|
|||||||
Users: map[string]*server.User{
|
Users: map[string]*server.User{
|
||||||
"test_user": user,
|
"test_user": user,
|
||||||
},
|
},
|
||||||
|
Settings: &server.Settings{
|
||||||
|
PeerLoginExpirationEnabled: true,
|
||||||
|
PeerLoginExpiration: time.Hour,
|
||||||
|
},
|
||||||
}, user, nil
|
}, user, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -58,38 +71,15 @@ func initTestMetaData(peers ...*server.Peer) *Peers {
|
|||||||
// Tests the GetPeers endpoint reachable in the route /api/peers
|
// Tests the GetPeers endpoint reachable in the route /api/peers
|
||||||
// Use the metadata generated by initTestMetaData() to check for values
|
// Use the metadata generated by initTestMetaData() to check for values
|
||||||
func TestGetPeers(t *testing.T) {
|
func TestGetPeers(t *testing.T) {
|
||||||
tt := []struct {
|
|
||||||
name string
|
|
||||||
expectedStatus int
|
|
||||||
requestType string
|
|
||||||
requestPath string
|
|
||||||
requestBody io.Reader
|
|
||||||
expectedArray bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "GetPeersMetaData",
|
|
||||||
requestType: http.MethodGet,
|
|
||||||
requestPath: "/api/peers/",
|
|
||||||
expectedStatus: http.StatusOK,
|
|
||||||
expectedArray: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GetPeer",
|
|
||||||
requestType: http.MethodGet,
|
|
||||||
requestPath: "/api/peers/" + testPeerID,
|
|
||||||
expectedStatus: http.StatusOK,
|
|
||||||
expectedArray: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
peer := &server.Peer{
|
peer := &server.Peer{
|
||||||
ID: testPeerID,
|
ID: testPeerID,
|
||||||
Key: "key",
|
Key: "key",
|
||||||
SetupKey: "setupkey",
|
SetupKey: "setupkey",
|
||||||
IP: net.ParseIP("100.64.0.1"),
|
IP: net.ParseIP("100.64.0.1"),
|
||||||
Status: &server.PeerStatus{},
|
Status: &server.PeerStatus{},
|
||||||
Name: "PeerName",
|
Name: "PeerName",
|
||||||
|
LoginExpirationEnabled: false,
|
||||||
Meta: server.PeerSystemMeta{
|
Meta: server.PeerSystemMeta{
|
||||||
Hostname: "hostname",
|
Hostname: "hostname",
|
||||||
GoOS: "GoOS",
|
GoOS: "GoOS",
|
||||||
@ -101,6 +91,49 @@ func TestGetPeers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expectedUpdatedPeer := peer.Copy()
|
||||||
|
expectedUpdatedPeer.LoginExpirationEnabled = true
|
||||||
|
expectedUpdatedPeer.SSHEnabled = true
|
||||||
|
expectedUpdatedPeer.Name = "New Name"
|
||||||
|
|
||||||
|
tt := []struct {
|
||||||
|
name string
|
||||||
|
expectedStatus int
|
||||||
|
requestType string
|
||||||
|
requestPath string
|
||||||
|
requestBody io.Reader
|
||||||
|
expectedArray bool
|
||||||
|
expectedPeer *server.Peer
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "GetPeersMetaData",
|
||||||
|
requestType: http.MethodGet,
|
||||||
|
requestPath: "/api/peers/",
|
||||||
|
expectedStatus: http.StatusOK,
|
||||||
|
expectedArray: true,
|
||||||
|
expectedPeer: peer,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GetPeer",
|
||||||
|
requestType: http.MethodGet,
|
||||||
|
requestPath: "/api/peers/" + testPeerID,
|
||||||
|
expectedStatus: http.StatusOK,
|
||||||
|
expectedArray: false,
|
||||||
|
expectedPeer: peer,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PutPeer",
|
||||||
|
requestType: http.MethodPut,
|
||||||
|
requestPath: "/api/peers/" + testPeerID,
|
||||||
|
expectedStatus: http.StatusOK,
|
||||||
|
expectedArray: false,
|
||||||
|
requestBody: bytes.NewBufferString("{\"login_expiration_enabled\":true,\"name\":\"New Name\",\"ssh_enabled\":true}"),
|
||||||
|
expectedPeer: expectedUpdatedPeer,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
p := initTestMetaData(peer)
|
p := initTestMetaData(peer)
|
||||||
|
|
||||||
for _, tc := range tt {
|
for _, tc := range tt {
|
||||||
@ -112,6 +145,7 @@ func TestGetPeers(t *testing.T) {
|
|||||||
router := mux.NewRouter()
|
router := mux.NewRouter()
|
||||||
router.HandleFunc("/api/peers/", p.GetPeers).Methods("GET")
|
router.HandleFunc("/api/peers/", p.GetPeers).Methods("GET")
|
||||||
router.HandleFunc("/api/peers/{id}", p.HandlePeer).Methods("GET")
|
router.HandleFunc("/api/peers/{id}", p.HandlePeer).Methods("GET")
|
||||||
|
router.HandleFunc("/api/peers/{id}", p.HandlePeer).Methods("PUT")
|
||||||
router.ServeHTTP(recorder, req)
|
router.ServeHTTP(recorder, req)
|
||||||
|
|
||||||
res := recorder.Result()
|
res := recorder.Result()
|
||||||
@ -144,10 +178,12 @@ func TestGetPeers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, got.Name, peer.Name)
|
assert.Equal(t, got.Name, tc.expectedPeer.Name)
|
||||||
assert.Equal(t, got.Version, peer.Meta.WtVersion)
|
assert.Equal(t, got.Version, tc.expectedPeer.Meta.WtVersion)
|
||||||
assert.Equal(t, got.Ip, peer.IP.String())
|
assert.Equal(t, got.Ip, tc.expectedPeer.IP.String())
|
||||||
assert.Equal(t, got.Os, "OS core")
|
assert.Equal(t, got.Os, "OS core")
|
||||||
|
assert.Equal(t, got.LoginExpirationEnabled, tc.expectedPeer.LoginExpirationEnabled)
|
||||||
|
assert.Equal(t, got.SshEnabled, tc.expectedPeer.SSHEnabled)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,15 +86,17 @@ func (p *Peer) Copy() *Peer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoginExpired indicates whether peer's login has expired or not.
|
// LoginExpired indicates whether the peer's login has expired or not.
|
||||||
// If Peer.LastLogin plus the expiresIn duration has happened already then login has expired.
|
// If Peer.LastLogin plus the expiresIn duration has happened already; then login has expired.
|
||||||
// Return true if login has expired, false otherwise and time left to expiration (negative when expired).
|
// Return true if a login has expired, false otherwise, and time left to expiration (negative when expired).
|
||||||
// Expiration can be disabled/enabled on the Account or Peer level.
|
// Login expiration can be disabled/enabled on a Peer level via Peer.LoginExpirationEnabled property.
|
||||||
|
// Login expiration can also be disabled/enabled globally on the Account level via Settings.PeerLoginExpirationEnabled
|
||||||
|
// and if disabled on the Account level, then Peer.LoginExpirationEnabled is ineffective.
|
||||||
func (p *Peer) LoginExpired(accountSettings *Settings) (bool, time.Duration) {
|
func (p *Peer) LoginExpired(accountSettings *Settings) (bool, time.Duration) {
|
||||||
expiresAt := p.LastLogin.Add(accountSettings.PeerLoginExpiration)
|
expiresAt := p.LastLogin.Add(accountSettings.PeerLoginExpiration)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
left := expiresAt.Sub(now)
|
timeLeft := expiresAt.Sub(now)
|
||||||
return accountSettings.PeerLoginExpirationEnabled && p.LoginExpirationEnabled && (left <= 0), left
|
return accountSettings.PeerLoginExpirationEnabled && p.LoginExpirationEnabled && (timeLeft <= 0), timeLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
// FQDN returns peers FQDN combined of the peer's DNS label and the system's DNS domain
|
// FQDN returns peers FQDN combined of the peer's DNS label and the system's DNS domain
|
||||||
@ -206,7 +208,7 @@ func (am *DefaultAccountManager) MarkPeerConnected(peerPubKey string, connected
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePeer updates peer. Only Peer.Name and Peer.SSHEnabled can be updated.
|
// UpdatePeer updates peer. Only Peer.Name, Peer.SSHEnabled, and Peer.LoginExpirationEnabled can be updated.
|
||||||
func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Peer) (*Peer, error) {
|
func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Peer) (*Peer, error) {
|
||||||
|
|
||||||
unlock := am.Store.AcquireAccountLock(accountID)
|
unlock := am.Store.AcquireAccountLock(accountID)
|
||||||
@ -246,6 +248,16 @@ func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Pe
|
|||||||
am.storeEvent(userID, peer.ID, accountID, activity.PeerRenamed, peer.EventMeta(am.GetDNSDomain()))
|
am.storeEvent(userID, peer.ID, accountID, activity.PeerRenamed, peer.EventMeta(am.GetDNSDomain()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if peer.LoginExpirationEnabled != update.LoginExpirationEnabled {
|
||||||
|
peer.LoginExpirationEnabled = update.LoginExpirationEnabled
|
||||||
|
|
||||||
|
event := activity.PeerLoginExpirationEnabled
|
||||||
|
if !update.LoginExpirationEnabled {
|
||||||
|
event = activity.PeerLoginExpirationDisabled
|
||||||
|
}
|
||||||
|
am.storeEvent(userID, peer.IP.String(), accountID, event, peer.EventMeta(am.GetDNSDomain()))
|
||||||
|
}
|
||||||
|
|
||||||
account.UpdatePeer(peer)
|
account.UpdatePeer(peer)
|
||||||
|
|
||||||
err = am.Store.SaveAccount(account)
|
err = am.Store.SaveAccount(account)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user