diff --git a/api/connection.go b/api/connection.go index 6c9e4f440..095710ebe 100644 --- a/api/connection.go +++ b/api/connection.go @@ -26,7 +26,7 @@ type Connection interface { UpdateObject(bucketName string, key []byte, object interface{}) error UpdateObjectFunc(bucketName string, key []byte, object any, updateFn func()) error DeleteObject(bucketName string, key []byte) error - DeleteAllObjects(bucketName string, matching func(o interface{}) (id int, ok bool)) error + DeleteAllObjects(bucketName string, obj interface{}, matching func(o interface{}) (id int, ok bool)) error GetNextIdentifier(bucketName string) int CreateObject(bucketName string, fn func(uint64) (int, interface{})) error CreateObjectWithId(bucketName string, id int, obj interface{}) error diff --git a/api/database/boltdb/db.go b/api/database/boltdb/db.go index c7fa80bd5..40411ce14 100644 --- a/api/database/boltdb/db.go +++ b/api/database/boltdb/db.go @@ -267,13 +267,12 @@ func (connection *DbConnection) DeleteObject(bucketName string, key []byte) erro // DeleteAllObjects delete all objects where matching() returns (id, ok). // TODO: think about how to return the error inside (maybe change ok to type err, and use "notfound"? -func (connection *DbConnection) DeleteAllObjects(bucketName string, matching func(o interface{}) (id int, ok bool)) error { +func (connection *DbConnection) DeleteAllObjects(bucketName string, obj interface{}, matching func(o interface{}) (id int, ok bool)) error { return connection.Batch(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) cursor := bucket.Cursor() for k, v := cursor.First(); k != nil; k, v = cursor.Next() { - var obj interface{} err := connection.UnmarshalObject(v, &obj) if err != nil { return err diff --git a/api/dataservices/interface.go b/api/dataservices/interface.go index e936f5de1..3f7ab6ed9 100644 --- a/api/dataservices/interface.go +++ b/api/dataservices/interface.go @@ -279,6 +279,7 @@ type ( DeleteTeamMembershipByUserID(userID portainer.UserID) error DeleteTeamMembershipByTeamID(teamID portainer.TeamID) error BucketName() string + DeleteTeamMembershipByTeamIDAndUserID(teamID portainer.TeamID, userID portainer.UserID) error } // TunnelServerService represents a service for managing data associated to the tunnel server diff --git a/api/dataservices/teammembership/teammembership.go b/api/dataservices/teammembership/teammembership.go index 6d8d82208..7e211df84 100644 --- a/api/dataservices/teammembership/teammembership.go +++ b/api/dataservices/teammembership/teammembership.go @@ -144,6 +144,7 @@ func (service *Service) DeleteTeamMembership(ID portainer.TeamMembershipID) erro func (service *Service) DeleteTeamMembershipByUserID(userID portainer.UserID) error { return service.connection.DeleteAllObjects( BucketName, + &portainer.TeamMembership{}, func(obj interface{}) (id int, ok bool) { membership, ok := obj.(portainer.TeamMembership) if !ok { @@ -164,6 +165,7 @@ func (service *Service) DeleteTeamMembershipByUserID(userID portainer.UserID) er func (service *Service) DeleteTeamMembershipByTeamID(teamID portainer.TeamID) error { return service.connection.DeleteAllObjects( BucketName, + &portainer.TeamMembership{}, func(obj interface{}) (id int, ok bool) { membership, ok := obj.(portainer.TeamMembership) if !ok { @@ -179,3 +181,23 @@ func (service *Service) DeleteTeamMembershipByTeamID(teamID portainer.TeamID) er return -1, false }) } + +func (service *Service) DeleteTeamMembershipByTeamIDAndUserID(teamID portainer.TeamID, userID portainer.UserID) error { + return service.connection.DeleteAllObjects( + BucketName, + &portainer.TeamMembership{}, + func(obj interface{}) (id int, ok bool) { + membership, ok := obj.(portainer.TeamMembership) + if !ok { + log.Debug().Str("obj", fmt.Sprintf("%#v", obj)).Msg("failed to convert to TeamMembership object") + //return fmt.Errorf("Failed to convert to TeamMembership object: %s", obj) + return -1, false + } + + if membership.TeamID == teamID && membership.UserID == userID { + return int(membership.ID), true + } + + return -1, false + }) +} diff --git a/app/portainer/settings/authentication/ldap/ldap-custom-group-search/ldap-custom-group-search.html b/app/portainer/settings/authentication/ldap/ldap-custom-group-search/ldap-custom-group-search.html index 5a9bfa32d..43ef624d1 100644 --- a/app/portainer/settings/authentication/ldap/ldap-custom-group-search/ldap-custom-group-search.html +++ b/app/portainer/settings/authentication/ldap/ldap-custom-group-search/ldap-custom-group-search.html @@ -35,6 +35,17 @@ +
+ + + Users removal synchronize between groups and teams only available in + business edition. + + +