* Add option to prevent LDAP from deactivating everything on empty search * Update options/locale/locale_en-US.ini Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>tags/v1.21.12.1
| @@ -61,6 +61,10 @@ var ( | |||||
| Name: "admin-filter", | Name: "admin-filter", | ||||
| Usage: "An LDAP filter specifying if a user should be given administrator privileges.", | Usage: "An LDAP filter specifying if a user should be given administrator privileges.", | ||||
| }, | }, | ||||
| cli.BoolFlag{ | |||||
| Name: "allow-deactivate-all", | |||||
| Usage: "Allow empty search results to deactivate all users.", | |||||
| }, | |||||
| cli.StringFlag{ | cli.StringFlag{ | ||||
| Name: "username-attribute", | Name: "username-attribute", | ||||
| Usage: "The attribute of the user’s LDAP record containing the user name.", | Usage: "The attribute of the user’s LDAP record containing the user name.", | ||||
| @@ -231,6 +235,9 @@ func parseLdapConfig(c *cli.Context, config *models.LDAPConfig) error { | |||||
| if c.IsSet("admin-filter") { | if c.IsSet("admin-filter") { | ||||
| config.Source.AdminFilter = c.String("admin-filter") | config.Source.AdminFilter = c.String("admin-filter") | ||||
| } | } | ||||
| if c.IsSet("allow-deactivate-all") { | |||||
| config.Source.AllowDeactivateAll = c.Bool("allow-deactivate-all") | |||||
| } | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -1780,6 +1780,15 @@ func SyncExternalUsers(ctx context.Context) { | |||||
| continue | continue | ||||
| } | } | ||||
| if len(sr) == 0 { | |||||
| if !s.LDAP().AllowDeactivateAll { | |||||
| log.Error("LDAP search found no entries but did not report an error. Refusing to deactivate all users") | |||||
| continue | |||||
| } else { | |||||
| log.Warn("LDAP search found no entries but did not report an error. All users will be deactivated as per settings") | |||||
| } | |||||
| } | |||||
| for _, su := range sr { | for _, su := range sr { | ||||
| select { | select { | ||||
| case <-ctx.Done(): | case <-ctx.Done(): | ||||
| @@ -30,6 +30,7 @@ type AuthenticationForm struct { | |||||
| SearchPageSize int | SearchPageSize int | ||||
| Filter string | Filter string | ||||
| AdminFilter string | AdminFilter string | ||||
| AllowDeactivateAll bool | |||||
| IsActive bool | IsActive bool | ||||
| IsSyncEnabled bool | IsSyncEnabled bool | ||||
| SMTPAuth string | SMTPAuth string | ||||
| @@ -47,6 +47,7 @@ type Source struct { | |||||
| Filter string // Query filter to validate entry | Filter string // Query filter to validate entry | ||||
| AdminFilter string // Query filter to check if user is admin | AdminFilter string // Query filter to check if user is admin | ||||
| Enabled bool // if this source is disabled | Enabled bool // if this source is disabled | ||||
| AllowDeactivateAll bool // Allow an empty search response to deactivate all users from this source | |||||
| } | } | ||||
| // SearchResult : user data | // SearchResult : user data | ||||
| @@ -1851,6 +1851,7 @@ auths.attribute_surname = Surname Attribute | |||||
| auths.attribute_mail = Email Attribute | auths.attribute_mail = Email Attribute | ||||
| auths.attribute_ssh_public_key = Public SSH Key Attribute | auths.attribute_ssh_public_key = Public SSH Key Attribute | ||||
| auths.attributes_in_bind = Fetch Attributes in Bind DN Context | auths.attributes_in_bind = Fetch Attributes in Bind DN Context | ||||
| auths.allow_deactivate_all = Allow an empty search result to deactivate all users | |||||
| auths.use_paged_search = Use Paged Search | auths.use_paged_search = Use Paged Search | ||||
| auths.search_page_size = Page Size | auths.search_page_size = Page Size | ||||
| auths.filter = User Filter | auths.filter = User Filter | ||||
| @@ -130,6 +130,7 @@ func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig { | |||||
| SearchPageSize: pageSize, | SearchPageSize: pageSize, | ||||
| Filter: form.Filter, | Filter: form.Filter, | ||||
| AdminFilter: form.AdminFilter, | AdminFilter: form.AdminFilter, | ||||
| AllowDeactivateAll: form.AllowDeactivateAll, | |||||
| Enabled: true, | Enabled: true, | ||||
| }, | }, | ||||
| } | } | ||||
| @@ -112,6 +112,12 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| <div class="inline field"> | |||||
| <div class="ui checkbox"> | |||||
| <label for="allow_deactivate_all"><strong>{{.i18n.Tr "admin.auths.allow_deactivate_all"}}</strong></label> | |||||
| <input id="allow_deactivate_all" name="allow_deactivate_all" type="checkbox" {{if $cfg.AllowDeactivateAll}}checked{{end}}> | |||||
| </div> | |||||
| </div> | |||||
| {{end}} | {{end}} | ||||
| <!-- SMTP --> | <!-- SMTP --> | ||||