Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Automatic Merge
  • Loading branch information
mattermost-build committed Apr 12, 2024
1 parent cee5974 commit 6b9c604
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 6 deletions.
85 changes: 85 additions & 0 deletions server/channels/api4/user_test.go
Expand Up @@ -4272,6 +4272,91 @@ func TestSwitchAccount(t *testing.T) {
_, appErr := th.App.Srv().Store().User().UpdateAuthData(th.BasicUser.Id, model.UserAuthServiceGitlab, &fakeAuthData, th.BasicUser.Email, true)
require.NoError(t, appErr)

t.Run("From GitLab to Email", func(t *testing.T) {
sr = &model.SwitchRequest{
CurrentService: model.UserAuthServiceGitlab,
NewService: model.UserAuthServiceEmail,
Email: th.BasicUser.Email,
NewPassword: th.BasicUser.Password,
}

t.Run("Switching from OAuth to email is disabled if EnableSignUpWithEmail is false", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.EmailSettings.EnableSignUpWithEmail = false })
t.Cleanup(func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.EmailSettings.EnableSignUpWithEmail = true })
})

_, resp, err = th.Client.SwitchAccountType(context.Background(), sr)
require.Error(t, err)
assert.Equal(t, "api.user.auth_switch.not_available.email_signup_disabled.app_error", err.(*model.AppError).Id)
CheckForbiddenStatus(t, resp)
})

t.Run("Switching from OAuth to email is disabled if EnableSignInWithEmail and EnableSignInWithUsername is false", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.EmailSettings.EnableSignInWithEmail = false
*cfg.EmailSettings.EnableSignInWithUsername = false
})
t.Cleanup(func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.EmailSettings.EnableSignInWithEmail = true
*cfg.EmailSettings.EnableSignInWithUsername = true
})
})

_, resp, err = th.Client.SwitchAccountType(context.Background(), sr)
require.Error(t, err)
assert.Equal(t, "api.user.auth_switch.not_available.login_disabled.app_error", err.(*model.AppError).Id)
CheckForbiddenStatus(t, resp)
})
})

t.Run("From LDAP to Email", func(t *testing.T) {
_, err = th.App.Srv().Store().User().UpdateAuthData(th.BasicUser.Id, model.UserAuthServiceLdap, &fakeAuthData, th.BasicUser.Email, true)
require.NoError(t, err)

t.Cleanup(func() {
_, err = th.App.Srv().Store().User().UpdateAuthData(th.BasicUser.Id, model.UserAuthServiceGitlab, &fakeAuthData, th.BasicUser.Email, true)
require.NoError(t, err)
})

sr = &model.SwitchRequest{
CurrentService: model.UserAuthServiceLdap,
NewService: model.UserAuthServiceEmail,
Email: th.BasicUser.Email,
NewPassword: th.BasicUser.Password,
}

t.Run("Switching from LDAP to email is disabled if EnableSignUpWithEmail is false", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.EmailSettings.EnableSignUpWithEmail = false })
t.Cleanup(func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.EmailSettings.EnableSignUpWithEmail = true })
})

_, resp, err = th.Client.SwitchAccountType(context.Background(), sr)
require.Error(t, err)
assert.Equal(t, "api.user.auth_switch.not_available.email_signup_disabled.app_error", err.(*model.AppError).Id)
CheckForbiddenStatus(t, resp)
})
t.Run("Switching from LDAP to email is disabled if EnableSignInWithEmail and EnableSignInWithUsername is false", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.EmailSettings.EnableSignInWithEmail = false
*cfg.EmailSettings.EnableSignInWithUsername = false
})
t.Cleanup(func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.EmailSettings.EnableSignInWithEmail = true
*cfg.EmailSettings.EnableSignInWithUsername = true
})
})

_, resp, err = th.Client.SwitchAccountType(context.Background(), sr)
require.Error(t, err)
assert.Equal(t, "api.user.auth_switch.not_available.login_disabled.app_error", err.(*model.AppError).Id)
CheckForbiddenStatus(t, resp)
})
})

sr = &model.SwitchRequest{
CurrentService: model.UserAuthServiceGitlab,
NewService: model.UserAuthServiceEmail,
Expand Down
8 changes: 8 additions & 0 deletions server/channels/app/ldap.go
Expand Up @@ -129,6 +129,14 @@ func (a *App) SwitchLdapToEmail(c request.CTX, ldapPassword, code, email, newPas
return "", model.NewAppError("ldapToEmail", "api.user.ldap_to_email.not_available.app_error", nil, "", http.StatusForbidden)
}

if !*a.Config().EmailSettings.EnableSignUpWithEmail {
return "", model.NewAppError("SwitchEmailToLdap", "api.user.auth_switch.not_available.email_signup_disabled.app_error", nil, "", http.StatusForbidden)
}

if !*a.Config().EmailSettings.EnableSignInWithEmail && !*a.Config().EmailSettings.EnableSignInWithUsername {
return "", model.NewAppError("SwitchEmailToLdap", "api.user.auth_switch.not_available.login_disabled.app_error", nil, "", http.StatusForbidden)
}

user, err := a.GetUserByEmail(email)
if err != nil {
return "", err
Expand Down
8 changes: 8 additions & 0 deletions server/channels/app/oauth.go
Expand Up @@ -986,6 +986,14 @@ func (a *App) SwitchOAuthToEmail(c request.CTX, email, password, requesterId str
return "", model.NewAppError("oauthToEmail", "api.user.oauth_to_email.not_available.app_error", nil, "", http.StatusForbidden)
}

if !*a.Config().EmailSettings.EnableSignUpWithEmail {
return "", model.NewAppError("SwitchOAuthToEmail", "api.user.auth_switch.not_available.email_signup_disabled.app_error", nil, "", http.StatusForbidden)
}

if !*a.Config().EmailSettings.EnableSignInWithEmail && !*a.Config().EmailSettings.EnableSignInWithUsername {
return "", model.NewAppError("SwitchOAuthToEmail", "api.user.auth_switch.not_available.login_disabled.app_error", nil, "", http.StatusForbidden)
}

user, err := a.GetUserByEmail(email)
if err != nil {
return "", err
Expand Down
8 changes: 8 additions & 0 deletions server/i18n/en.json
Expand Up @@ -3994,6 +3994,14 @@
"id": "api.user.add_user_to_group_syncables.not_ldap_user.app_error",
"translation": "not an ldap user"
},
{
"id": "api.user.auth_switch.not_available.email_signup_disabled.app_error",
"translation": "Authentication Transfer is not available as email signup is disabled."
},
{
"id": "api.user.auth_switch.not_available.login_disabled.app_error",
"translation": "Authentication Transfer is not available as neither email login nor username login is enabled."
},
{
"id": "api.user.authorize_oauth_user.bad_response.app_error",
"translation": "Bad response from token request."
Expand Down
Expand Up @@ -547,3 +547,141 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
</div>
</div>
`;

exports[`components/user_settings/display/UserSettingsDisplay should match snapshot, to email 1`] = `
<div>
<SettingMobileHeader
closeModal={[MockFunction]}
collapseModal={[MockFunction]}
text={
<Memo(MemoizedFormattedMessage)
defaultMessage="Security Settings"
id="user.settings.security.title"
/>
}
/>
<div
className="user-settings"
>
<SettingDesktopHeader
text={
<Memo(MemoizedFormattedMessage)
defaultMessage="Security Settings"
id="user.settings.security.title"
/>
}
/>
<div
className="divider-dark first"
/>
<SettingItem
active={false}
areAllSectionsInactive={false}
max={null}
section="password"
title={
<Memo(MemoizedFormattedMessage)
defaultMessage="Password"
id="user.settings.security.password"
/>
}
updateSection={[Function]}
/>
<div
className="divider-light"
/>
<Connect(MfaSection)
active={false}
areAllSectionsInactive={false}
updateSection={[Function]}
/>
<div
className="divider-light"
/>
<div
className="divider-light"
/>
<Connect(UserAccessTokenSection)
active={false}
areAllSectionsInactive={false}
setRequireConfirm={[MockFunction]}
updateSection={[Function]}
user={
Object {
"auth_service": "openid",
"id": "user_id",
}
}
/>
<div
className="divider-light"
/>
<SettingItem
active={false}
areAllSectionsInactive={false}
describe={
<Memo(MemoizedFormattedMessage)
defaultMessage="OpenID"
id="user.settings.security.openid"
/>
}
max={null}
section="signin"
title="Sign-in Method"
updateSection={[Function]}
/>
<div
className="divider-dark"
/>
<br />
<ToggleModalButton
className="security-links color--link"
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": Object {
"$$typeof": Symbol(react.memo),
"compare": null,
"type": [Function],
},
"compare": null,
"type": [Function],
}
}
id="viewAccessHistory"
modalId="access_history"
>
<i
className="fa fa-clock-o"
title="Access History Icon"
/>
<MemoizedFormattedMessage
defaultMessage="View Access History"
id="user.settings.security.viewHistory"
/>
</ToggleModalButton>
<ToggleModalButton
className="security-links color--link mt-2"
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
id="viewAndLogOutOfActiveSessions"
modalId="activity_log"
>
<i
className="fa fa-clock-o"
title="Active Sessions Icon"
/>
<MemoizedFormattedMessage
defaultMessage="View and Log Out of Active Sessions"
id="user.settings.security.logoutActiveSessions"
/>
</ToggleModalButton>
</div>
</div>
`;
Expand Up @@ -35,7 +35,7 @@ function mapStateToProps(state: GlobalState, ownProps: Props) {
const userHasTokenRole = UserUtils.hasUserAccessTokenRole(ownProps.user.roles) || UserUtils.isSystemAdmin(ownProps.user.roles);

const enableOAuthServiceProvider = config.EnableOAuthServiceProvider === 'true';
const enableSignUpWithEmail = config.EnableSignUpWithEmail === 'true';
const allowedToSwitchToEmail = config.EnableSignUpWithEmail === 'true' && (config.EnableSignInWithEmail === 'true' || config.EnableSignInWithUsername === 'true');
const enableSignUpWithGitLab = config.EnableSignUpWithGitLab === 'true';
const enableSignUpWithGoogle = config.EnableSignUpWithGoogle === 'true';
const enableSignUpWithOpenId = config.EnableSignUpWithOpenId === 'true';
Expand All @@ -47,7 +47,7 @@ function mapStateToProps(state: GlobalState, ownProps: Props) {
return {
canUseAccessTokens: tokensEnabled && userHasTokenRole,
enableOAuthServiceProvider,
enableSignUpWithEmail,
allowedToSwitchToEmail,
enableSignUpWithGitLab,
enableSignUpWithGoogle,
enableSignUpWithOpenId,
Expand Down
Expand Up @@ -8,6 +8,7 @@ import type {OAuthApp} from '@mattermost/types/integrations';
import type {UserProfile} from '@mattermost/types/users';

import type {MockIntl} from 'tests/helpers/intl-test-helper';
import Constants from 'utils/constants';
import type * as Utils from 'utils/utils';

import {SecurityTab} from './user_settings_security';
Expand Down Expand Up @@ -37,7 +38,7 @@ describe('components/user_settings/display/UserSettingsDisplay', () => {
},
canUseAccessTokens: true,
enableOAuthServiceProvider: false,
enableSignUpWithEmail: true,
allowedToSwitchToEmail: true,
enableSignUpWithGitLab: false,
enableSignUpWithGoogle: true,
enableSignUpWithOpenId: false,
Expand Down Expand Up @@ -80,6 +81,18 @@ describe('components/user_settings/display/UserSettingsDisplay', () => {
expect(wrapper).toMatchSnapshot();
});

test('should match snapshot, to email', () => {
const user = {
id: 'user_id',
auth_service: Constants.OPENID_SERVICE,
};

const props = {...requiredProps, user: user as UserProfile};

const wrapper = shallow<SecurityTab>(<SecurityTab {...props}/>);
expect(wrapper).toMatchSnapshot();
});

test('componentDidMount() should have called getAuthorizedOAuthApps', () => {
const props = {...requiredProps, enableOAuthServiceProvider: true};

Expand Down
Expand Up @@ -56,7 +56,7 @@ type Props = {
setRequireConfirm: () => void;
canUseAccessTokens: boolean;
enableOAuthServiceProvider: boolean;
enableSignUpWithEmail: boolean;
allowedToSwitchToEmail: boolean;
enableSignUpWithGitLab: boolean;
enableSignUpWithGoogle: boolean;
enableSignUpWithOpenId: boolean;
Expand Down Expand Up @@ -671,7 +671,7 @@ export class SecurityTab extends React.PureComponent<Props, State> {
</div>
);
}
} else if (this.props.enableSignUpWithEmail) {
} else if (this.props.allowedToSwitchToEmail) {
let link;
if (user.auth_service === Constants.LDAP_SERVICE) {
link =
Expand Down Expand Up @@ -966,7 +966,7 @@ export class SecurityTab extends React.PureComponent<Props, State> {
// If there are other sign-in methods and either email is enabled or the user's account is email, then allow switching
let signInSection;
if (
(this.props.enableSignUpWithEmail || user.auth_service === '') &&
(this.props.allowedToSwitchToEmail || user.auth_service === '') &&
numMethods > 0 &&
this.props.experimentalEnableAuthenticationTransfer
) {
Expand Down

0 comments on commit 6b9c604

Please sign in to comment.