diff --git a/management/server/account_test.go b/management/server/account_test.go index 5be4b09b951..eb3215a8e32 100644 --- a/management/server/account_test.go +++ b/management/server/account_test.go @@ -3,7 +3,6 @@ package server import ( "context" "crypto/sha256" - "database/sql" b64 "encoding/base64" "encoding/json" "fmt" @@ -17,6 +16,7 @@ import ( "time" "github.com/golang-jwt/jwt" + "github.com/netbirdio/netbird/management/server/util" resourceTypes "github.com/netbirdio/netbird/management/server/networks/resources/types" routerTypes "github.com/netbirdio/netbird/management/server/networks/routers/types" @@ -188,7 +188,7 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) { LoginExpired: true, }, UserID: userID, - LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30), + LastLogin: util.ToPtr(time.Now().UTC().Add(-time.Hour * 24 * 30 * 30)), }, "peer-2": { ID: peerID2, @@ -202,7 +202,7 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) { LoginExpired: false, }, UserID: userID, - LastLogin: time.Now().UTC(), + LastLogin: util.ToPtr(time.Now().UTC()), LoginExpirationEnabled: true, }, }, @@ -226,7 +226,7 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) { LoginExpired: true, }, UserID: userID, - LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30), + LastLogin: util.ToPtr(time.Now().UTC().Add(-time.Hour * 24 * 30 * 30)), LoginExpirationEnabled: true, }, "peer-2": { @@ -241,7 +241,7 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) { LoginExpired: true, }, UserID: userID, - LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30), + LastLogin: util.ToPtr(time.Now().UTC().Add(-time.Hour * 24 * 30 * 30)), LoginExpirationEnabled: true, }, }, @@ -814,7 +814,6 @@ func TestDefaultAccountManager_MarkPATUsed(t *testing.T) { "tokenId": { ID: "tokenId", HashedToken: encodedHashedToken, - LastUsed: time.Time{}, }, }, } @@ -1097,7 +1096,7 @@ func genUsers(p string, n int) map[string]*types.User { users[fmt.Sprintf("%s-%d", p, i)] = &types.User{ Id: fmt.Sprintf("%s-%d", p, i), Role: types.UserRoleAdmin, - LastLogin: sql.NullTime{Time: now, Valid: !now.IsZero()}, + LastLogin: util.ToPtr(now), CreatedAt: now, Issued: "api", AutoGroups: []string{"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}, @@ -1749,10 +1748,10 @@ func TestAccount_Copy(t *testing.T) { ID: "pat1", Name: "First PAT", HashedToken: "SoMeHaShEdToKeN", - ExpirationDate: time.Now().UTC().AddDate(0, 0, 7), + ExpirationDate: util.ToPtr(time.Now().UTC().AddDate(0, 0, 7)), CreatedBy: "user1", CreatedAt: time.Now().UTC(), - LastUsed: time.Now().UTC(), + LastUsed: util.ToPtr(time.Now().UTC()), }, }, }, @@ -2108,7 +2107,7 @@ func TestAccount_GetExpiredPeers(t *testing.T) { Connected: true, LoginExpired: false, }, - LastLogin: time.Now().UTC().Add(-30 * time.Minute), + LastLogin: util.ToPtr(time.Now().UTC().Add(-30 * time.Minute)), UserID: userID, }, "peer-2": { @@ -2119,7 +2118,7 @@ func TestAccount_GetExpiredPeers(t *testing.T) { Connected: true, LoginExpired: false, }, - LastLogin: time.Now().UTC().Add(-2 * time.Hour), + LastLogin: util.ToPtr(time.Now().UTC().Add(-2 * time.Hour)), UserID: userID, }, @@ -2131,7 +2130,7 @@ func TestAccount_GetExpiredPeers(t *testing.T) { Connected: true, LoginExpired: false, }, - LastLogin: time.Now().UTC().Add(-1 * time.Hour), + LastLogin: util.ToPtr(time.Now().UTC().Add(-1 * time.Hour)), UserID: userID, }, }, @@ -2193,7 +2192,7 @@ func TestAccount_GetInactivePeers(t *testing.T) { Connected: false, LoginExpired: false, }, - LastLogin: time.Now().UTC().Add(-30 * time.Minute), + LastLogin: util.ToPtr(time.Now().UTC().Add(-30 * time.Minute)), UserID: userID, }, "peer-2": { @@ -2204,7 +2203,7 @@ func TestAccount_GetInactivePeers(t *testing.T) { Connected: false, LoginExpired: false, }, - LastLogin: time.Now().UTC().Add(-2 * time.Hour), + LastLogin: util.ToPtr(time.Now().UTC().Add(-2 * time.Hour)), UserID: userID, }, "peer-3": { @@ -2215,7 +2214,7 @@ func TestAccount_GetInactivePeers(t *testing.T) { Connected: true, LoginExpired: false, }, - LastLogin: time.Now().UTC().Add(-1 * time.Hour), + LastLogin: util.ToPtr(time.Now().UTC().Add(-1 * time.Hour)), UserID: userID, }, }, @@ -2485,7 +2484,7 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) { LoginExpired: false, }, LoginExpirationEnabled: true, - LastLogin: time.Now().UTC(), + LastLogin: util.ToPtr(time.Now().UTC()), UserID: userID, }, "peer-2": { @@ -2645,7 +2644,7 @@ func TestAccount_GetNextInactivePeerExpiration(t *testing.T) { LastSeen: time.Now().Add(-1 * time.Second), }, InactivityExpirationEnabled: true, - LastLogin: time.Now().UTC(), + LastLogin: util.ToPtr(time.Now().UTC()), UserID: userID, }, "peer-2": { @@ -2723,8 +2722,8 @@ func TestAccount_SetJWTGroups(t *testing.T) { }, Settings: &types.Settings{GroupsPropagationEnabled: true, JWTGroupsEnabled: true, JWTGroupsClaimName: "groups"}, Users: map[string]*types.User{ - "user1": {Id: "user1", AccountID: "accountID"}, - "user2": {Id: "user2", AccountID: "accountID"}, + "user1": {Id: "user1", AccountID: "accountID", CreatedAt: time.Now()}, + "user2": {Id: "user2", AccountID: "accountID", CreatedAt: time.Now()}, }, } diff --git a/management/server/group_test.go b/management/server/group_test.go index 834388d1ef3..cc90f187b5e 100644 --- a/management/server/group_test.go +++ b/management/server/group_test.go @@ -355,6 +355,7 @@ func initTestGroupAccount(am *DefaultAccountManager) (*DefaultAccountManager, *t setupKey := &types.SetupKey{ Id: "example setup key", AutoGroups: []string{groupForSetupKeys.ID}, + UpdatedAt: time.Now(), } user := &types.User{ diff --git a/management/server/http/handlers/routes/routes_handler_test.go b/management/server/http/handlers/routes/routes_handler_test.go index 4cee3ee306b..45c4655871a 100644 --- a/management/server/http/handlers/routes/routes_handler_test.go +++ b/management/server/http/handlers/routes/routes_handler_test.go @@ -11,6 +11,7 @@ import ( "net/netip" "testing" + "github.com/netbirdio/netbird/management/server/util" "github.com/stretchr/testify/require" "github.com/netbirdio/netbird/management/server/http/api" @@ -239,7 +240,7 @@ func TestRoutesHandlers(t *testing.T) { Id: existingRouteID, Description: "Post", NetworkId: "awesomeNet", - Network: toPtr("192.168.0.0/16"), + Network: util.ToPtr("192.168.0.0/16"), Peer: &existingPeerID, NetworkType: route.IPv4NetworkString, Masquerade: false, @@ -259,7 +260,7 @@ func TestRoutesHandlers(t *testing.T) { Id: existingRouteID, Description: "Post", NetworkId: "domainNet", - Network: toPtr("invalid Prefix"), + Network: util.ToPtr("invalid Prefix"), KeepRoute: true, Domains: &[]string{existingDomain}, Peer: &existingPeerID, @@ -281,7 +282,7 @@ func TestRoutesHandlers(t *testing.T) { Id: existingRouteID, Description: "Post", NetworkId: "awesomeNet", - Network: toPtr("192.168.0.0/16"), + Network: util.ToPtr("192.168.0.0/16"), Peer: &existingPeerID, NetworkType: route.IPv4NetworkString, Masquerade: false, @@ -385,7 +386,7 @@ func TestRoutesHandlers(t *testing.T) { Id: existingRouteID, Description: "Post", NetworkId: "awesomeNet", - Network: toPtr("192.168.0.0/16"), + Network: util.ToPtr("192.168.0.0/16"), Peer: &existingPeerID, NetworkType: route.IPv4NetworkString, Masquerade: false, @@ -404,7 +405,7 @@ func TestRoutesHandlers(t *testing.T) { Id: existingRouteID, Description: "Post", NetworkId: "awesomeNet", - Network: toPtr("invalid Prefix"), + Network: util.ToPtr("invalid Prefix"), Domains: &[]string{existingDomain}, Peer: &existingPeerID, NetworkType: route.DomainNetworkString, @@ -425,7 +426,7 @@ func TestRoutesHandlers(t *testing.T) { Id: existingRouteID, Description: "Post", NetworkId: "awesomeNet", - Network: toPtr("192.168.0.0/16"), + Network: util.ToPtr("192.168.0.0/16"), Peer: &emptyString, PeerGroups: &[]string{existingGroupID}, NetworkType: route.IPv4NetworkString, @@ -663,7 +664,3 @@ func toApiRoute(t *testing.T, r *route.Route) *api.Route { require.NoError(t, err, "Failed to convert route") return apiRoute } - -func toPtr[T any](v T) *T { - return &v -} diff --git a/management/server/http/handlers/setup_keys/setupkeys_handler.go b/management/server/http/handlers/setup_keys/setupkeys_handler.go index da805b29eaf..e71a3606a68 100644 --- a/management/server/http/handlers/setup_keys/setupkeys_handler.go +++ b/management/server/http/handlers/setup_keys/setupkeys_handler.go @@ -240,7 +240,7 @@ func toResponseBody(key *types.SetupKey) *api.SetupKey { Id: key.Id, Key: key.KeySecret, Name: key.Name, - Expires: key.ExpiresAt, + Expires: key.ExpirationTime(), Type: string(key.Type), Valid: key.IsValid(), Revoked: key.Revoked, diff --git a/management/server/http/handlers/users/pat_handler_test.go b/management/server/http/handlers/users/pat_handler_test.go index 21bdc461e9a..866d744ac0d 100644 --- a/management/server/http/handlers/users/pat_handler_test.go +++ b/management/server/http/handlers/users/pat_handler_test.go @@ -12,6 +12,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/gorilla/mux" + "github.com/netbirdio/netbird/management/server/util" "github.com/stretchr/testify/assert" "github.com/netbirdio/netbird/management/server/http/api" @@ -42,19 +43,19 @@ var testAccount = &types.Account{ ID: existingTokenID, Name: "My first token", HashedToken: "someHash", - ExpirationDate: time.Now().UTC().AddDate(0, 0, 7), + ExpirationDate: util.ToPtr(time.Now().UTC().AddDate(0, 0, 7)), CreatedBy: existingUserID, CreatedAt: time.Now().UTC(), - LastUsed: time.Now().UTC(), + LastUsed: util.ToPtr(time.Now().UTC()), }, "token2": { ID: "token2", Name: "My second token", HashedToken: "someOtherHash", - ExpirationDate: time.Now().UTC().AddDate(0, 0, 7), + ExpirationDate: util.ToPtr(time.Now().UTC().AddDate(0, 0, 7)), CreatedBy: existingUserID, CreatedAt: time.Now().UTC(), - LastUsed: time.Now().UTC(), + LastUsed: util.ToPtr(time.Now().UTC()), }, }, }, @@ -248,8 +249,8 @@ func toTokenResponse(serverToken types.PersonalAccessToken) api.PersonalAccessTo Id: serverToken.ID, Name: serverToken.Name, CreatedAt: serverToken.CreatedAt, - LastUsed: &serverToken.LastUsed, + LastUsed: serverToken.LastUsed, CreatedBy: serverToken.CreatedBy, - ExpirationDate: serverToken.ExpirationDate, + ExpirationDate: serverToken.ExpirationTime(), } } diff --git a/management/server/http/middleware/auth_middleware_test.go b/management/server/http/middleware/auth_middleware_test.go index b0d970c5dca..41bdb7fc58a 100644 --- a/management/server/http/middleware/auth_middleware_test.go +++ b/management/server/http/middleware/auth_middleware_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/golang-jwt/jwt" + "github.com/netbirdio/netbird/management/server/util" "github.com/netbirdio/netbird/management/server/http/middleware/bypass" "github.com/netbirdio/netbird/management/server/jwtclaims" @@ -39,10 +40,10 @@ var testAccount = &types.Account{ ID: tokenID, Name: "My first token", HashedToken: "someHash", - ExpirationDate: time.Now().UTC().AddDate(0, 0, 7), + ExpirationDate: util.ToPtr(time.Now().UTC().AddDate(0, 0, 7)), CreatedBy: userID, CreatedAt: time.Now().UTC(), - LastUsed: time.Now().UTC(), + LastUsed: util.ToPtr(time.Now().UTC()), }, }, }, diff --git a/management/server/peer_test.go b/management/server/peer_test.go index 9ad67d2bf6d..f5511493b96 100644 --- a/management/server/peer_test.go +++ b/management/server/peer_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "github.com/netbirdio/netbird/management/server/util" "github.com/rs/xid" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" @@ -80,7 +81,7 @@ func TestPeer_LoginExpired(t *testing.T) { t.Run(c.name, func(t *testing.T) { peer := &nbpeer.Peer{ LoginExpirationEnabled: c.expirationEnabled, - LastLogin: c.lastLogin, + LastLogin: util.ToPtr(c.lastLogin), UserID: userID, } @@ -141,7 +142,7 @@ func TestPeer_SessionExpired(t *testing.T) { } peer := &nbpeer.Peer{ InactivityExpirationEnabled: c.expirationEnabled, - LastLogin: c.lastLogin, + LastLogin: util.ToPtr(c.lastLogin), Status: peerStatus, UserID: userID, } @@ -1209,7 +1210,7 @@ func Test_RegisterPeerByUser(t *testing.T) { UserID: existingUserID, Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()}, SSHEnabled: false, - LastLogin: time.Now(), + LastLogin: util.ToPtr(time.Now()), } addedPeer, _, _, err := am.AddPeer(context.Background(), "", existingUserID, newPeer) diff --git a/management/server/setupkey_test.go b/management/server/setupkey_test.go index f728db5d458..8632fed3b9f 100644 --- a/management/server/setupkey_test.go +++ b/management/server/setupkey_test.go @@ -66,7 +66,7 @@ func TestDefaultAccountManager_SaveSetupKey(t *testing.T) { t.Fatal(err) } - assertKey(t, newKey, keyName, revoked, "reusable", 0, key.CreatedAt, key.ExpiresAt, + assertKey(t, newKey, keyName, revoked, "reusable", 0, key.CreatedAt, key.ExpirationTime(), key.Id, time.Now().UTC(), autoGroups, true) // check the corresponding events that should have been generated @@ -391,7 +391,7 @@ func TestSetupKey_Copy(t *testing.T) { key, _ := types.GenerateSetupKey("key name", types.SetupKeyOneOff, time.Hour, []string{}, types.SetupKeyUnlimitedUsage, false) keyCopy := key.Copy() - assertKey(t, keyCopy, key.Name, key.Revoked, string(key.Type), key.UsedTimes, key.CreatedAt, key.ExpiresAt, key.Id, + assertKey(t, keyCopy, key.Name, key.Revoked, string(key.Type), key.UsedTimes, key.CreatedAt, key.ExpirationTime(), key.Id, key.UpdatedAt, key.AutoGroups, true) } diff --git a/management/server/types/setupkey.go b/management/server/types/setupkey.go index 29f288ef398..e2415bae556 100644 --- a/management/server/types/setupkey.go +++ b/management/server/types/setupkey.go @@ -39,7 +39,7 @@ type SetupKey struct { Name string Type SetupKeyType CreatedAt time.Time - ExpiresAt time.Time + ExpiresAt *time.Time UpdatedAt time.Time `gorm:"autoUpdateTime:false"` // Revoked indicates whether the key was revoked or not (we don't remove them for tracking purposes) Revoked bool @@ -95,6 +95,14 @@ func (key *SetupKey) LastUsedTime() time.Time { return time.Time{} } +// ExpirationTime returns the expiration time of the setup key. +func (key *SetupKey) ExpirationTime() time.Time { + if key.ExpiresAt != nil { + return *key.ExpiresAt + } + return time.Time{} +} + // HiddenKey returns the Key value hidden with "*" and a 5 character prefix. // E.g., "831F6*******************************" func HiddenKey(key string, length int) string { @@ -125,10 +133,10 @@ func (key *SetupKey) IsRevoked() bool { // IsExpired if key was expired func (key *SetupKey) IsExpired() bool { - if key.ExpiresAt.IsZero() { + if key.ExpirationTime().IsZero() { return false } - return time.Now().After(key.ExpiresAt) + return time.Now().After(key.ExpirationTime()) } // IsOverUsed if the key was used too many times. SetupKey.UsageLimit == 0 indicates the unlimited usage. @@ -149,9 +157,9 @@ func GenerateSetupKey(name string, t SetupKeyType, validFor time.Duration, autoG limit = 1 } - expiresAt := time.Time{} + var expiresAt *time.Time if validFor != 0 { - expiresAt = time.Now().UTC().Add(validFor) + expiresAt = util.ToPtr(time.Now().UTC().Add(validFor)) } hashedKey := sha256.Sum256([]byte(key)) diff --git a/management/server/user_test.go b/management/server/user_test.go index 8c40e2e0ca9..a028d164b5d 100644 --- a/management/server/user_test.go +++ b/management/server/user_test.go @@ -2,7 +2,6 @@ package server import ( "context" - "database/sql" "fmt" "reflect" "testing" @@ -11,6 +10,7 @@ import ( "github.com/eko/gocache/v3/cache" cacheStore "github.com/eko/gocache/v3/store" "github.com/google/go-cmp/cmp" + "github.com/netbirdio/netbird/management/server/util" nbpeer "github.com/netbirdio/netbird/management/server/peer" "github.com/netbirdio/netbird/management/server/store" @@ -322,14 +322,14 @@ func TestUser_Copy(t *testing.T) { ID: "pat1", Name: "First PAT", HashedToken: "SoMeHaShEdToKeN", - ExpirationDate: time.Now().AddDate(0, 0, 7), + ExpirationDate: util.ToPtr(time.Now().AddDate(0, 0, 7)), CreatedBy: "userId", CreatedAt: time.Now(), - LastUsed: time.Now(), + LastUsed: util.ToPtr(time.Now()), }, }, Blocked: false, - LastLogin: sql.NullTime{Time: time.Now().UTC(), Valid: true}, + LastLogin: util.ToPtr(time.Now().UTC()), CreatedAt: time.Now().UTC(), Issued: "test", IntegrationReference: integration_reference.IntegrationReference{