Skip to content

Commit 8e16c9f

Browse files
IDP Group Filtering Update (#3656)
* fix(go): prevent creating network with fully-masked cidr; * fix(go): filter out static non-user nodes; * fix(go): prevent creation of networks with only broadcast and network ip; * fix(go): cleanup user and groups resources on idp sync; * fix(go): add "$filter" only once; * fix(go): add "$filter" only once; * fix(go): add "$filter" only once; * fix(go): escape "$filter"; * feat(go): assign synced group global user role id; --------- Co-authored-by: VishalDalwadi <[email protected]> Co-authored-by: Vishal Dalwadi <[email protected]>
1 parent a741f8f commit 8e16c9f

File tree

4 files changed

+133
-57
lines changed

4 files changed

+133
-57
lines changed

pro/auth/sync.go

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ import (
1111
"github.com/gravitl/netmaker/logger"
1212
"github.com/gravitl/netmaker/logic"
1313
"github.com/gravitl/netmaker/models"
14+
"github.com/gravitl/netmaker/mq"
1415
"github.com/gravitl/netmaker/pro/idp"
1516
"github.com/gravitl/netmaker/pro/idp/azure"
1617
"github.com/gravitl/netmaker/pro/idp/google"
1718
"github.com/gravitl/netmaker/pro/idp/okta"
1819
proLogic "github.com/gravitl/netmaker/pro/logic"
20+
"github.com/gravitl/netmaker/servercfg"
1921
)
2022

2123
var (
@@ -149,7 +151,8 @@ func syncUsers(idpUsers []idp.User) error {
149151
for _, user := range idpUsers {
150152
if user.AccountArchived {
151153
// delete the user if it has been archived.
152-
_ = logic.DeleteUser(user.Username)
154+
user := dbUsersMap[user.Username]
155+
_ = deleteAndCleanUpUser(&user)
153156
continue
154157
}
155158

@@ -209,14 +212,14 @@ func syncUsers(idpUsers []idp.User) error {
209212
}
210213

211214
for _, user := range dbUsersMap {
212-
if user.ExternalIdentityProviderID == "" {
213-
continue
214-
}
215-
if _, ok := idpUsersMap[user.UserName]; !ok {
216-
// delete the user if it has been deleted on idp.
217-
err = logic.DeleteUser(user.UserName)
218-
if err != nil {
219-
return err
215+
if user.ExternalIdentityProviderID != "" {
216+
if _, ok := idpUsersMap[user.UserName]; !ok {
217+
// delete the user if it has been deleted on idp
218+
// or is filtered out.
219+
err = deleteAndCleanUpUser(&user)
220+
if err != nil {
221+
return err
222+
}
220223
}
221224
}
222225
}
@@ -277,7 +280,11 @@ func syncGroups(idpGroups []idp.Group) error {
277280
dbGroup.ExternalIdentityProviderID = group.ID
278281
dbGroup.Name = group.Name
279282
dbGroup.Default = false
280-
dbGroup.NetworkRoles = make(map[models.NetworkID]map[models.UserRoleID]struct{})
283+
dbGroup.NetworkRoles = map[models.NetworkID]map[models.UserRoleID]struct{}{
284+
models.AllNetworks: {
285+
proLogic.GetDefaultGlobalUserRoleID(): {},
286+
},
287+
}
281288
err := proLogic.CreateUserGroup(&dbGroup)
282289
if err != nil {
283290
return err
@@ -324,8 +331,9 @@ func syncGroups(idpGroups []idp.Group) error {
324331
for _, group := range dbGroups {
325332
if group.ExternalIdentityProviderID != "" {
326333
if _, ok := idpGroupsMap[group.ExternalIdentityProviderID]; !ok {
327-
// delete the group if it has been deleted on idp.
328-
err = proLogic.DeleteUserGroup(group.ID)
334+
// delete the group if it has been deleted on idp
335+
// or is filtered out.
336+
err = proLogic.DeleteAndCleanUpGroup(&group)
329337
if err != nil {
330338
return err
331339
}
@@ -355,6 +363,7 @@ func GetIDPSyncStatus() models.IDPSyncStatus {
355363
}
356364
}
357365
}
366+
358367
func filterUsersByGroupMembership(idpUsers []idp.User, idpGroups []idp.Group) []idp.User {
359368
usersMap := make(map[string]int)
360369
for i, user := range idpUsers {
@@ -395,14 +404,14 @@ func filterGroupsByMembers(idpGroups []idp.Group, idpUsers []idp.User) []idp.Gro
395404
if _, ok := usersMap[member]; ok {
396405
members = append(members, member)
397406
}
407+
}
398408

399-
if len(members) > 0 {
400-
// the group at index `i` has members from the `idpUsers` list,
401-
// so we keep it.
402-
filteredGroupsMap[i] = true
403-
// filter out members that were not provided in the `idpUsers` list.
404-
idpGroups[i].Members = members
405-
}
409+
if len(members) > 0 {
410+
// the group at index `i` has members from the `idpUsers` list,
411+
// so we keep it.
412+
filteredGroupsMap[i] = true
413+
// filter out members that were not provided in the `idpUsers` list.
414+
idpGroups[i].Members = members
406415
}
407416
}
408417

@@ -415,3 +424,37 @@ func filterGroupsByMembers(idpGroups []idp.Group, idpUsers []idp.User) []idp.Gro
415424

416425
return filteredGroups
417426
}
427+
428+
// TODO: deduplicate
429+
// The cyclic import between the package logic and mq requires this
430+
// function to be duplicated in multiple places.
431+
func deleteAndCleanUpUser(user *models.User) error {
432+
err := logic.DeleteUser(user.UserName)
433+
if err != nil {
434+
return err
435+
}
436+
437+
// check and delete extclient with this ownerID
438+
go func() {
439+
extclients, err := logic.GetAllExtClients()
440+
if err != nil {
441+
return
442+
}
443+
for _, extclient := range extclients {
444+
if extclient.OwnerID == user.UserName {
445+
err = logic.DeleteExtClientAndCleanup(extclient)
446+
if err == nil {
447+
_ = mq.PublishDeletedClientPeerUpdate(&extclient)
448+
}
449+
}
450+
}
451+
452+
go logic.DeleteUserInvite(user.UserName)
453+
go mq.PublishPeerUpdate(false)
454+
if servercfg.IsDNSMode() {
455+
go logic.SetDNS()
456+
}
457+
}()
458+
459+
return nil
460+
}

pro/controllers/users.go

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,13 @@ func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
808808
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot delete default user group"), "badrequest"))
809809
return
810810
}
811-
err = proLogic.DeleteUserGroup(models.UserGroupID(gid))
811+
err = proLogic.DeleteAndCleanUpGroup(&userG)
812812
if err != nil {
813813
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
814814
return
815815
}
816+
817+
// TODO: log event in proLogic.DeleteAndCleanUpGroup so that all deletions are logged.
816818
logic.LogEvent(&models.Event{
817819
Action: models.Delete,
818820
Source: models.Subject{
@@ -828,42 +830,7 @@ func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
828830
},
829831
Origin: models.Dashboard,
830832
})
831-
replacePeers := false
832-
go func() {
833-
for networkID := range userG.NetworkRoles {
834-
acls, err := logic.ListAclsByNetwork(networkID)
835-
if err != nil {
836-
continue
837-
}
838-
839-
for _, acl := range acls {
840-
var hasGroupSrc bool
841-
newAclSrc := make([]models.AclPolicyTag, 0)
842-
for _, src := range acl.Src {
843-
if src.ID == models.UserGroupAclID && src.Value == userG.ID.String() {
844-
hasGroupSrc = true
845-
} else {
846-
newAclSrc = append(newAclSrc, src)
847-
}
848-
}
849833

850-
if hasGroupSrc {
851-
if len(newAclSrc) == 0 {
852-
// no other src exists, delete acl.
853-
_ = logic.DeleteAcl(acl)
854-
} else {
855-
// other sources exist, update acl.
856-
acl.Src = newAclSrc
857-
_ = logic.UpsertAcl(acl)
858-
}
859-
replacePeers = true
860-
}
861-
}
862-
}
863-
}()
864-
865-
go proLogic.UpdatesUserGwAccessOnGrpUpdates(userG.ID, userG.NetworkRoles, make(map[models.NetworkID]map[models.UserRoleID]struct{}))
866-
go mq.PublishPeerUpdate(replacePeers)
867834
logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user group")
868835
}
869836

pro/idp/azure/azure.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,15 +226,19 @@ func (a *Client) getAccessToken() (string, error) {
226226
}
227227

228228
func buildPrefixFilter(field string, prefixes []string) string {
229+
return url.PathEscape("$filter=" + buildCondition(field, prefixes))
230+
}
231+
232+
func buildCondition(field string, prefixes []string) string {
229233
if len(prefixes) == 0 {
230234
return ""
231235
}
232236

233237
if len(prefixes) == 1 {
234-
return fmt.Sprintf("$filter=startswith(%s,'%s')", field, prefixes[0])
238+
return fmt.Sprintf("startswith(%s,'%s')", field, prefixes[0])
235239
}
236240

237-
return buildPrefixFilter(field, prefixes[:1]) + "%20or%20" + buildPrefixFilter(field, prefixes[1:])
241+
return buildCondition(field, prefixes[:1]) + " or " + buildCondition(field, prefixes[1:])
238242
}
239243

240244
type getUsersResponse struct {

pro/logic/user_mgmt.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,22 @@ func GetUserGroup(gid models.UserGroupID) (models.UserGroup, error) {
620620
return ug, nil
621621
}
622622

623+
func GetDefaultGlobalAdminGroupID() models.UserGroupID {
624+
return globalNetworksAdminGroupID
625+
}
626+
627+
func GetDefaultGlobalUserGroupID() models.UserGroupID {
628+
return globalNetworksUserGroupID
629+
}
630+
631+
func GetDefaultGlobalAdminRoleID() models.UserRoleID {
632+
return globalNetworksAdminRoleID
633+
}
634+
635+
func GetDefaultGlobalUserRoleID() models.UserRoleID {
636+
return globalNetworksUserRoleID
637+
}
638+
623639
func GetDefaultNetworkAdminGroupID(networkID models.NetworkID) models.UserGroupID {
624640
return models.UserGroupID(fmt.Sprintf("%s-%s-grp", networkID, models.NetworkAdmin))
625641
}
@@ -672,6 +688,52 @@ func UpdateUserGroup(g models.UserGroup) error {
672688
return database.Insert(g.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)
673689
}
674690

691+
func DeleteAndCleanUpGroup(group *models.UserGroup) error {
692+
err := DeleteUserGroup(group.ID)
693+
if err != nil {
694+
return err
695+
}
696+
697+
go func() {
698+
var replacePeers bool
699+
for networkID := range group.NetworkRoles {
700+
acls, err := logic.ListAclsByNetwork(networkID)
701+
if err != nil {
702+
continue
703+
}
704+
705+
for _, acl := range acls {
706+
var hasGroupSrc bool
707+
newAclSrc := make([]models.AclPolicyTag, 0)
708+
for _, src := range acl.Src {
709+
if src.ID == models.UserGroupAclID && src.Value == group.ID.String() {
710+
hasGroupSrc = true
711+
} else {
712+
newAclSrc = append(newAclSrc, src)
713+
}
714+
}
715+
716+
if hasGroupSrc {
717+
if len(newAclSrc) == 0 {
718+
// no other src exists, delete acl.
719+
_ = logic.DeleteAcl(acl)
720+
} else {
721+
// other sources exist, update acl.
722+
acl.Src = newAclSrc
723+
_ = logic.UpsertAcl(acl)
724+
}
725+
replacePeers = true
726+
}
727+
}
728+
}
729+
730+
go UpdatesUserGwAccessOnGrpUpdates(group.ID, group.NetworkRoles, make(map[models.NetworkID]map[models.UserRoleID]struct{}))
731+
go mq.PublishPeerUpdate(replacePeers)
732+
}()
733+
734+
return nil
735+
}
736+
675737
// DeleteUserGroup - deletes user group
676738
func DeleteUserGroup(gid models.UserGroupID) error {
677739
g, err := GetUserGroup(gid)

0 commit comments

Comments
 (0)