mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-19 03:16:58 +02:00
Autopropagate peers by JWT groups (#1037)
Enhancements to Peer Group Assignment: 1. Auto-assigned groups are now applied to all peers every time a user logs into the network. 2. Feature activation is available in the account settings. 3. API modifications included to support these changes for account settings updates. 4. If propagation is enabled, updates to a user's auto-assigned groups are immediately reflected across all user peers. 5. With the JWT group sync feature active, auto-assigned groups are forcefully updated whenever a peer logs in using user credentials.
This commit is contained in:
committed by
GitHub
parent
8eca83f3cb
commit
e5e69b1f75
@@ -216,7 +216,6 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) {
|
||||
assert.Len(t, networkMap.Peers, len(testCase.expectedPeers))
|
||||
assert.Len(t, networkMap.OfflinePeers, len(testCase.expectedOfflinePeers))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestNewAccount(t *testing.T) {
|
||||
@@ -1931,6 +1930,120 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccount_AddJWTGroups(t *testing.T) {
|
||||
// create a new account
|
||||
account := &Account{
|
||||
Peers: map[string]*Peer{
|
||||
"peer1": {ID: "peer1", Key: "key1", UserID: "user1"},
|
||||
"peer2": {ID: "peer2", Key: "key2", UserID: "user1"},
|
||||
"peer3": {ID: "peer3", Key: "key3", UserID: "user1"},
|
||||
"peer4": {ID: "peer4", Key: "key4", UserID: "user2"},
|
||||
"peer5": {ID: "peer5", Key: "key5", UserID: "user2"},
|
||||
},
|
||||
Groups: map[string]*Group{
|
||||
"group1": {ID: "group1", Name: "group1", Issued: GroupIssuedAPI, Peers: []string{}},
|
||||
},
|
||||
Settings: &Settings{GroupsPropagationEnabled: true},
|
||||
Users: map[string]*User{
|
||||
"user1": {Id: "user1"},
|
||||
"user2": {Id: "user2"},
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("api group already exists", func(t *testing.T) {
|
||||
updated := account.AddJWTGroups("user1", []string{"group1"})
|
||||
assert.False(t, updated, "account should not be updated")
|
||||
assert.Empty(t, account.Users["user1"].AutoGroups, "auto groups must be empty")
|
||||
})
|
||||
|
||||
t.Run("add jwt group", func(t *testing.T) {
|
||||
updated := account.AddJWTGroups("user1", []string{"group1", "group2"})
|
||||
assert.True(t, updated, "account should be updated")
|
||||
assert.Len(t, account.Groups, 2, "new group should be added")
|
||||
assert.Len(t, account.Users["user1"].AutoGroups, 1, "new group should be added")
|
||||
assert.Contains(t, account.Groups, account.Users["user1"].AutoGroups[0], "groups must contain group2 from user groups")
|
||||
})
|
||||
|
||||
t.Run("existed group not update", func(t *testing.T) {
|
||||
updated := account.AddJWTGroups("user1", []string{"group2"})
|
||||
assert.False(t, updated, "account should not be updated")
|
||||
assert.Len(t, account.Groups, 2, "groups count should not be changed")
|
||||
})
|
||||
|
||||
t.Run("add new group", func(t *testing.T) {
|
||||
updated := account.AddJWTGroups("user2", []string{"group1", "group3"})
|
||||
assert.True(t, updated, "account should be updated")
|
||||
assert.Len(t, account.Groups, 3, "new group should be added")
|
||||
assert.Len(t, account.Users["user2"].AutoGroups, 1, "new group should be added")
|
||||
assert.Contains(t, account.Groups, account.Users["user2"].AutoGroups[0], "groups must contain group3 from user groups")
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccount_UserGroupsAddToPeers(t *testing.T) {
|
||||
account := &Account{
|
||||
Peers: map[string]*Peer{
|
||||
"peer1": {ID: "peer1", Key: "key1", UserID: "user1"},
|
||||
"peer2": {ID: "peer2", Key: "key2", UserID: "user1"},
|
||||
"peer3": {ID: "peer3", Key: "key3", UserID: "user1"},
|
||||
"peer4": {ID: "peer4", Key: "key4", UserID: "user2"},
|
||||
"peer5": {ID: "peer5", Key: "key5", UserID: "user2"},
|
||||
},
|
||||
Groups: map[string]*Group{
|
||||
"group1": {ID: "group1", Name: "group1", Issued: GroupIssuedAPI, Peers: []string{}},
|
||||
"group2": {ID: "group2", Name: "group2", Issued: GroupIssuedAPI, Peers: []string{}},
|
||||
"group3": {ID: "group3", Name: "group3", Issued: GroupIssuedAPI, Peers: []string{}},
|
||||
},
|
||||
Users: map[string]*User{"user1": {Id: "user1"}, "user2": {Id: "user2"}},
|
||||
}
|
||||
|
||||
t.Run("add groups", func(t *testing.T) {
|
||||
account.UserGroupsAddToPeers("user1", "group1", "group2")
|
||||
assert.ElementsMatch(t, account.Groups["group1"].Peers, []string{"peer1", "peer2", "peer3"}, "group1 contains users peers")
|
||||
assert.ElementsMatch(t, account.Groups["group2"].Peers, []string{"peer1", "peer2", "peer3"}, "group2 contains users peers")
|
||||
})
|
||||
|
||||
t.Run("add same groups", func(t *testing.T) {
|
||||
account.UserGroupsAddToPeers("user1", "group1", "group2")
|
||||
assert.Len(t, account.Groups["group1"].Peers, 3, "peers amount in group1 didn't change")
|
||||
assert.Len(t, account.Groups["group2"].Peers, 3, "peers amount in group2 didn't change")
|
||||
})
|
||||
|
||||
t.Run("add second user peers", func(t *testing.T) {
|
||||
account.UserGroupsAddToPeers("user2", "group2")
|
||||
assert.ElementsMatch(t, account.Groups["group2"].Peers,
|
||||
[]string{"peer1", "peer2", "peer3", "peer4", "peer5"}, "group2 contains first and second user peers")
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccount_UserGroupsRemoveFromPeers(t *testing.T) {
|
||||
account := &Account{
|
||||
Peers: map[string]*Peer{
|
||||
"peer1": {ID: "peer1", Key: "key1", UserID: "user1"},
|
||||
"peer2": {ID: "peer2", Key: "key2", UserID: "user1"},
|
||||
"peer3": {ID: "peer3", Key: "key3", UserID: "user1"},
|
||||
"peer4": {ID: "peer4", Key: "key4", UserID: "user2"},
|
||||
"peer5": {ID: "peer5", Key: "key5", UserID: "user2"},
|
||||
},
|
||||
Groups: map[string]*Group{
|
||||
"group1": {ID: "group1", Name: "group1", Issued: GroupIssuedAPI, Peers: []string{"peer1", "peer2", "peer3"}},
|
||||
"group2": {ID: "group2", Name: "group2", Issued: GroupIssuedAPI, Peers: []string{"peer1", "peer2", "peer3", "peer4", "peer5"}},
|
||||
"group3": {ID: "group3", Name: "group3", Issued: GroupIssuedAPI, Peers: []string{"peer4", "peer5"}},
|
||||
},
|
||||
Users: map[string]*User{"user1": {Id: "user1"}, "user2": {Id: "user2"}},
|
||||
}
|
||||
|
||||
t.Run("remove groups", func(t *testing.T) {
|
||||
account.UserGroupsRemoveFromPeers("user1", "group1", "group2")
|
||||
assert.Empty(t, account.Groups["group1"].Peers, "remove all peers from group1")
|
||||
assert.ElementsMatch(t, account.Groups["group2"].Peers, []string{"peer4", "peer5"}, "group2 contains only second users peers")
|
||||
})
|
||||
|
||||
t.Run("remove group with no peers", func(t *testing.T) {
|
||||
account.UserGroupsRemoveFromPeers("user1", "group3")
|
||||
assert.Len(t, account.Groups["group3"].Peers, 2, "peers amount should not change")
|
||||
})
|
||||
}
|
||||
|
||||
func createManager(t *testing.T) (*DefaultAccountManager, error) {
|
||||
store, err := createStore(t)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user