Fixing LDAP editing of attributes (#2824)

Этот коммит содержится в:
Christopher Speller
2016-05-02 08:07:58 -04:00
родитель 3346a9a63a
Коммит c63e027aec
6 изменённых файлов: 210 добавлений и 139 удалений

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

@@ -145,7 +145,7 @@ test: start-docker
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=340s ./api || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=12s ./model || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./store || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./store || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./utils || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./web || exit 1
ifeq ($(BUILD_ENTERPRISE_READY),true)

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

@@ -3495,6 +3495,10 @@
"id": "store.sql_user.update.app_error",
"translation": "We couldn't update the account"
},
{
"id": "store.sql_user.update.can_not_change_ldap.app_error",
"translation": "Can not change fields set by LDAP"
},
{
"id": "store.sql_user.update.email_taken.app_error",
"translation": "This email is already taken. Please choose another."

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

@@ -136,7 +136,17 @@ func (us SqlUserStore) Update(user *model.User, allowActiveUpdate bool) StoreCha
if user.IsOAuthUser() {
user.Email = oldUser.Email
} else if !user.IsLDAPUser() && user.Email != oldUser.Email {
} else if user.IsLDAPUser() {
if user.Username != oldUser.Username ||
user.FirstName != oldUser.FirstName ||
user.LastName != oldUser.LastName ||
user.Email != oldUser.Email {
result.Err = model.NewLocAppError("SqlUserStore.Update", "store.sql_user.update.can_not_change_ldap.app_error", nil, "user_id="+user.Id)
storeChannel <- result
close(storeChannel)
return
}
} else if user.Email != oldUser.Email {
user.EmailVerified = false
}

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

@@ -77,6 +77,12 @@ func TestUserStoreUpdate(t *testing.T) {
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
u2 := &model.User{}
u2.Email = model.NewId()
u2.AuthService = "ldap"
Must(store.User().Save(u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
time.Sleep(100 * time.Millisecond)
if err := (<-store.User().Update(u1, false)).Err; err != nil {
@@ -92,6 +98,11 @@ func TestUserStoreUpdate(t *testing.T) {
if err := (<-store.User().Update(u1, false)).Err; err == nil {
t.Fatal("Update should have faile because id change")
}
u2.Email = model.NewId()
if err := (<-store.User().Update(u2, false)).Err; err == nil {
t.Fatal("Update should have failed because you can't modify LDAP fields")
}
}
func TestUserStoreUpdateLastPingAt(t *testing.T) {

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

@@ -259,6 +259,7 @@ func getClientConfig(c *model.Config) map[string]string {
props["EnableLdap"] = strconv.FormatBool(*c.LdapSettings.Enable)
props["LdapLoginFieldName"] = *c.LdapSettings.LoginFieldName
props["LdapPasswordFieldName"] = *c.LdapSettings.PasswordFieldName
props["NicknameAttributeSet"] = strconv.FormatBool(*c.LdapSettings.NicknameAttribute != "")
}
if *License.Features.MFA {

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

@@ -513,85 +513,100 @@ class UserSettingsGeneralTab extends React.Component {
const inputs = [];
if (this.props.activeSection === 'name') {
inputs.push(
<div
key='firstNameSetting'
className='form-group'
>
<label className='col-sm-5 control-label'>
<FormattedMessage
id='user.settings.general.firstName'
defaultMessage='First Name'
/>
</label>
<div className='col-sm-7'>
<input
className='form-control'
type='text'
onChange={this.updateFirstName}
value={this.state.firstName}
/>
let extraInfo;
let submit = null;
if (this.props.user.auth_service === '') {
inputs.push(
<div
key='firstNameSetting'
className='form-group'
>
<label className='col-sm-5 control-label'>
<FormattedMessage
id='user.settings.general.firstName'
defaultMessage='First Name'
/>
</label>
<div className='col-sm-7'>
<input
className='form-control'
type='text'
onChange={this.updateFirstName}
value={this.state.firstName}
/>
</div>
</div>
</div>
);
);
inputs.push(
<div
key='lastNameSetting'
className='form-group'
>
<label className='col-sm-5 control-label'>
<FormattedMessage
id='user.settings.general.lastName'
defaultMessage='Last Name'
/>
</label>
<div className='col-sm-7'>
<input
className='form-control'
type='text'
onChange={this.updateLastName}
value={this.state.lastName}
/>
inputs.push(
<div
key='lastNameSetting'
className='form-group'
>
<label className='col-sm-5 control-label'>
<FormattedMessage
id='user.settings.general.lastName'
defaultMessage='Last Name'
/>
</label>
<div className='col-sm-7'>
<input
className='form-control'
type='text'
onChange={this.updateLastName}
value={this.state.lastName}
/>
</div>
</div>
</div>
);
);
function notifClick(e) {
e.preventDefault();
this.updateSection('');
this.props.updateTab('notifications');
function notifClick(e) {
e.preventDefault();
this.updateSection('');
this.props.updateTab('notifications');
}
const notifLink = (
<a
href='#'
onClick={notifClick.bind(this)}
>
<FormattedMessage
id='user.settings.general.notificationsLink'
defaultMessage='Notifications'
/>
</a>
);
extraInfo = (
<span>
<FormattedMessage
id='user.settings.general.notificationsExtra'
defaultMessage='By default, you will receive mention notifications when someone types your first name. Go to {notify} settings to change this default.'
values={{
notify: (notifLink)
}}
/>
</span>
);
submit = this.submitName;
} else {
extraInfo = (
<span>
<FormattedMessage
id='user.settings.general.field_handled_externally'
defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so though your login provider.'
/>
</span>
);
}
const notifLink = (
<a
href='#'
onClick={notifClick.bind(this)}
>
<FormattedMessage
id='user.settings.general.notificationsLink'
defaultMessage='Notifications'
/>
</a>
);
const extraInfo = (
<span>
<FormattedMessage
id='user.settings.general.notificationsExtra'
defaultMessage='By default, you will receive mention notifications when someone types your first name. Go to {notify} settings to change this default.'
values={{
notify: (notifLink)
}}
/>
</span>
);
nameSection = (
<SettingItemMax
title={formatMessage(holders.fullName)}
inputs={inputs}
submit={this.submitName}
submit={submit}
server_error={serverError}
client_error={clientError}
updateSection={(e) => {
@@ -632,47 +647,62 @@ class UserSettingsGeneralTab extends React.Component {
let nicknameSection;
if (this.props.activeSection === 'nickname') {
let nicknameLabel = (
<FormattedMessage
id='user.settings.general.nickname'
defaultMessage='Nickname'
/>
);
if (Utils.isMobile()) {
nicknameLabel = '';
}
inputs.push(
<div
key='nicknameSetting'
className='form-group'
>
<label className='col-sm-5 control-label'>{nicknameLabel}</label>
<div className='col-sm-7'>
<input
className='form-control'
type='text'
onChange={this.updateNickname}
value={this.state.nickname}
let extraInfo;
let submit = null;
if (this.props.user.auth_service === 'ldap' && global.window.mm_config.NicknameAttributeSet) {
extraInfo = (
<span>
<FormattedMessage
id='user.settings.general.field_handled_externally'
defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so though your login provider.'
/>
</div>
</div>
);
const extraInfo = (
<span>
</span>
);
} else {
let nicknameLabel = (
<FormattedMessage
id='user.settings.general.nicknameExtra'
defaultMessage='Use Nickname for a name you might be called that is different from your first name and username. This is most often used when two or more people have similar sounding names and usernames.'
id='user.settings.general.nickname'
defaultMessage='Nickname'
/>
</span>
);
);
if (Utils.isMobile()) {
nicknameLabel = '';
}
inputs.push(
<div
key='nicknameSetting'
className='form-group'
>
<label className='col-sm-5 control-label'>{nicknameLabel}</label>
<div className='col-sm-7'>
<input
className='form-control'
type='text'
onChange={this.updateNickname}
value={this.state.nickname}
/>
</div>
</div>
);
extraInfo = (
<span>
<FormattedMessage
id='user.settings.general.nicknameExtra'
defaultMessage='Use Nickname for a name you might be called that is different from your first name and username. This is most often used when two or more people have similar sounding names and usernames.'
/>
</span>
);
submit = this.submitNickname;
}
nicknameSection = (
<SettingItemMax
title={formatMessage(holders.nickname)}
inputs={inputs}
submit={this.submitNickname}
submit={submit}
server_error={serverError}
client_error={clientError}
updateSection={(e) => {
@@ -708,48 +738,63 @@ class UserSettingsGeneralTab extends React.Component {
let usernameSection;
if (this.props.activeSection === 'username') {
let usernameLabel = (
<FormattedMessage
id='user.settings.general.username'
defaultMessage='Username'
/>
);
if (Utils.isMobile()) {
usernameLabel = '';
}
inputs.push(
<div
key='usernameSetting'
className='form-group'
>
<label className='col-sm-5 control-label'>{usernameLabel}</label>
<div className='col-sm-7'>
<input
maxLength={Constants.MAX_USERNAME_LENGTH}
className='form-control'
type='text'
onChange={this.updateUsername}
value={this.state.username}
/>
</div>
</div>
);
const extraInfo = (
<span>
let extraInfo;
let submit = null;
if (this.props.user.auth_service === '') {
let usernameLabel = (
<FormattedMessage
id='user.settings.general.usernameInfo'
defaultMessage='Pick something easy for teammates to recognize and recall.'
id='user.settings.general.username'
defaultMessage='Username'
/>
</span>
);
);
if (Utils.isMobile()) {
usernameLabel = '';
}
inputs.push(
<div
key='usernameSetting'
className='form-group'
>
<label className='col-sm-5 control-label'>{usernameLabel}</label>
<div className='col-sm-7'>
<input
maxLength={Constants.MAX_USERNAME_LENGTH}
className='form-control'
type='text'
onChange={this.updateUsername}
value={this.state.username}
/>
</div>
</div>
);
extraInfo = (
<span>
<FormattedMessage
id='user.settings.general.usernameInfo'
defaultMessage='Pick something easy for teammates to recognize and recall.'
/>
</span>
);
submit = this.submitUsername;
} else {
extraInfo = (
<span>
<FormattedMessage
id='user.settings.general.field_handled_externally'
defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so though your login provider.'
/>
</span>
);
}
usernameSection = (
<SettingItemMax
title={formatMessage(holders.username)}
inputs={inputs}
submit={this.submitUsername}
submit={submit}
server_error={serverError}
client_error={clientError}
updateSection={(e) => {