[MM-20061] Add System Admin filter to both LDAP and SAML (#13534)

* promote user to admin upon login

* Add SAML support for admin accounts

* update en.json

* update i18n

* Add tests as per comments

* change function name

* fix config.go

* invalidate cache so its not checking for cache when roles change

* add enable attribute and filter
Этот коммит содержится в:
Hossein Ahmadian-Yazdi
2020-01-13 12:50:01 -05:00
коммит произвёл GitHub
родитель 5f7ca55b13
Коммит dc24c9abe8
6 изменённых файлов: 183 добавлений и 12 удалений

Просмотреть файл

@@ -132,6 +132,7 @@ const (
SAML_SETTINGS_DEFAULT_ID_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_GUEST_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_ADMIN_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE = ""
SAML_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE = ""
@@ -1700,9 +1701,11 @@ type LdapSettings struct {
BindPassword *string
// Filtering
UserFilter *string
GroupFilter *string
GuestFilter *string
UserFilter *string
GroupFilter *string
GuestFilter *string
EnableAdminFilter *bool
AdminFilter *string
// Group Mapping
GroupDisplayNameAttribute *string
@@ -1746,6 +1749,10 @@ func (s *LdapSettings) SetDefaults() {
s.EnableSync = NewBool(*s.Enable)
}
if s.EnableAdminFilter == nil {
s.EnableAdminFilter = NewBool(false)
}
if s.LdapServer == nil {
s.LdapServer = NewString("")
}
@@ -1778,6 +1785,10 @@ func (s *LdapSettings) SetDefaults() {
s.GuestFilter = NewString("")
}
if s.AdminFilter == nil {
s.AdminFilter = NewString("")
}
if s.GroupFilter == nil {
s.GroupFilter = NewString("")
}
@@ -1927,15 +1938,17 @@ type SamlSettings struct {
PrivateKeyFile *string
// User Mapping
IdAttribute *string
GuestAttribute *string
FirstNameAttribute *string
LastNameAttribute *string
EmailAttribute *string
UsernameAttribute *string
NicknameAttribute *string
LocaleAttribute *string
PositionAttribute *string
IdAttribute *string
GuestAttribute *string
EnableAdminAttribute *bool
AdminAttribute *string
FirstNameAttribute *string
LastNameAttribute *string
EmailAttribute *string
UsernameAttribute *string
NicknameAttribute *string
LocaleAttribute *string
PositionAttribute *string
LoginButtonText *string
@@ -1957,6 +1970,10 @@ func (s *SamlSettings) SetDefaults() {
s.EnableSyncWithLdapIncludeAuth = NewBool(false)
}
if s.EnableAdminAttribute == nil {
s.EnableAdminAttribute = NewBool(false)
}
if s.Verify == nil {
s.Verify = NewBool(true)
}
@@ -2024,6 +2041,9 @@ func (s *SamlSettings) SetDefaults() {
if s.GuestAttribute == nil {
s.GuestAttribute = NewString(SAML_SETTINGS_DEFAULT_GUEST_ATTRIBUTE)
}
if s.AdminAttribute == nil {
s.AdminAttribute = NewString(SAML_SETTINGS_DEFAULT_ADMIN_ATTRIBUTE)
}
if s.FirstNameAttribute == nil {
s.FirstNameAttribute = NewString(SAML_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE)
}
@@ -2816,6 +2836,12 @@ func (s *LdapSettings) isValid() *AppError {
return NewAppError("LdapSettings.isValid", "ent.ldap.validate_guest_filter.app_error", nil, err.Error(), http.StatusBadRequest)
}
}
if *s.AdminFilter != "" {
if _, err := ldap.CompileFilter(*s.AdminFilter); err != nil {
return NewAppError("LdapSettings.isValid", "ent.ldap.validate_admin_filter.app_error", nil, err.Error(), http.StatusBadRequest)
}
}
}
return nil
@@ -2878,6 +2904,15 @@ func (s *SamlSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_guest_attribute.app_error", nil, "", http.StatusBadRequest)
}
}
if len(*s.AdminAttribute) > 0 {
if !(strings.Contains(*s.AdminAttribute, "=")) {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_admin_attribute.app_error", nil, "", http.StatusBadRequest)
}
if len(strings.Split(*s.AdminAttribute, "=")) != 2 {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_admin_attribute.app_error", nil, "", http.StatusBadRequest)
}
}
}
return nil

Просмотреть файл

@@ -171,6 +171,21 @@ func TestConfigOverwriteGuestSettings(t *testing.T) {
require.Equal(t, *c1.SamlSettings.GuestAttribute, attribute)
}
func TestConfigOverwriteAdminSettings(t *testing.T) {
const attribute = "FakeAttributeName"
c1 := Config{
SamlSettings: SamlSettings{
AdminAttribute: NewString(attribute),
},
}
c1.SetDefaults()
if *c1.SamlSettings.AdminAttribute != attribute {
t.Fatal("SamlSettings.AdminAttribute should be overwritten")
}
}
func TestConfigDefaultServiceSettingsExperimentalGroupUnreadChannels(t *testing.T) {
c1 := Config{}
c1.SetDefaults()
@@ -1069,6 +1084,105 @@ func TestLdapSettingsIsValid(t *testing.T) {
},
ExpectError: true,
},
{
Name: "valid Admin filter #1",
LdapSettings: LdapSettings{
Enable: NewBool(true),
LdapServer: NewString("server"),
BaseDN: NewString("basedn"),
EmailAttribute: NewString("email"),
UsernameAttribute: NewString("username"),
IdAttribute: NewString("id"),
LoginIdAttribute: NewString("loginid"),
AdminFilter: NewString("(property=value)"),
},
ExpectError: false,
},
{
Name: "invalid Admin filter #1",
LdapSettings: LdapSettings{
Enable: NewBool(true),
LdapServer: NewString("server"),
BaseDN: NewString("basedn"),
EmailAttribute: NewString("email"),
UsernameAttribute: NewString("username"),
IdAttribute: NewString("id"),
LoginIdAttribute: NewString("loginid"),
AdminFilter: NewString("("),
},
ExpectError: true,
},
{
Name: "invalid Admin filter #2",
LdapSettings: LdapSettings{
Enable: NewBool(true),
LdapServer: NewString("server"),
BaseDN: NewString("basedn"),
EmailAttribute: NewString("email"),
UsernameAttribute: NewString("username"),
IdAttribute: NewString("id"),
LoginIdAttribute: NewString("loginid"),
AdminFilter: NewString("()"),
},
ExpectError: true,
},
{
Name: "valid Admin filter #2",
LdapSettings: LdapSettings{
Enable: NewBool(true),
LdapServer: NewString("server"),
BaseDN: NewString("basedn"),
EmailAttribute: NewString("email"),
UsernameAttribute: NewString("username"),
IdAttribute: NewString("id"),
LoginIdAttribute: NewString("loginid"),
AdminFilter: NewString("(&(property=value)(otherthing=othervalue))"),
},
ExpectError: false,
},
{
Name: "valid Admin filter #3",
LdapSettings: LdapSettings{
Enable: NewBool(true),
LdapServer: NewString("server"),
BaseDN: NewString("basedn"),
EmailAttribute: NewString("email"),
UsernameAttribute: NewString("username"),
IdAttribute: NewString("id"),
LoginIdAttribute: NewString("loginid"),
AdminFilter: NewString("(&(property=value)(|(otherthing=othervalue)(other=thing)))"),
},
ExpectError: false,
},
{
Name: "invalid Admin filter #3",
LdapSettings: LdapSettings{
Enable: NewBool(true),
LdapServer: NewString("server"),
BaseDN: NewString("basedn"),
EmailAttribute: NewString("email"),
UsernameAttribute: NewString("username"),
IdAttribute: NewString("id"),
LoginIdAttribute: NewString("loginid"),
AdminFilter: NewString("(&(property=value)(|(otherthing=othervalue)(other=thing))"),
},
ExpectError: true,
},
{
Name: "invalid Admin filter #4",
LdapSettings: LdapSettings{
Enable: NewBool(true),
LdapServer: NewString("server"),
BaseDN: NewString("basedn"),
EmailAttribute: NewString("email"),
UsernameAttribute: NewString("username"),
IdAttribute: NewString("id"),
LoginIdAttribute: NewString("loginid"),
AdminFilter: NewString("(&(property=value)((otherthing=othervalue)(other=thing)))"),
},
ExpectError: true,
},
} {
t.Run(test.Name, func(t *testing.T) {
test.LdapSettings.SetDefaults()

Просмотреть файл

@@ -633,6 +633,10 @@ func (u *User) IsGuest() bool {
return IsInRole(u.Roles, SYSTEM_GUEST_ROLE_ID)
}
func (u *User) IsSystemAdmin() bool {
return IsInRole(u.Roles, SYSTEM_ADMIN_ROLE_ID)
}
// Make sure you acually want to use this function. In context.go there are functions to check permissions
// This function should not be used to check permissions.
func (u *User) IsInRole(inRole string) bool {