* Remove guest badge

* Address feedback

* Fix lint, test and i18n

* Fix test
Этот коммит содержится в:
Daniel Espino García
2023-06-30 11:06:18 +02:00
коммит произвёл GitHub
родитель 05cd245e97
Коммит fda5dd8468
18 изменённых файлов: 66 добавлений и 22 удалений

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

@@ -639,6 +639,7 @@ const defaultServerConfig: AdminConfig = {
},
GuestAccountsSettings: {
Enable: false,
HideTags: false,
AllowEmailAccounts: true,
EnforceMultifactorAuthentication: false,
RestrictCreationToDomains: '',

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

@@ -322,6 +322,7 @@ func GenerateLimitedClientConfig(c *model.Config, telemetryID string, license *m
props["EnableMultifactorAuthentication"] = strconv.FormatBool(*c.ServiceSettings.EnableMultifactorAuthentication)
props["EnforceMultifactorAuthentication"] = "false"
props["EnableGuestAccounts"] = strconv.FormatBool(*c.GuestAccountsSettings.Enable)
props["HideGuestTags"] = strconv.FormatBool(*c.GuestAccountsSettings.HideTags)
props["GuestAccountsEnforceMultifactorAuthentication"] = strconv.FormatBool(*c.GuestAccountsSettings.EnforceMultifactorAuthentication)
if license != nil {

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

@@ -860,6 +860,7 @@ func (ts *TelemetryService) trackConfig() {
ts.SendTelemetry(TrackConfigGuestAccounts, map[string]any{
"enable": *cfg.GuestAccountsSettings.Enable,
"hide_tag": *cfg.GuestAccountsSettings.HideTags,
"allow_email_accounts": *cfg.GuestAccountsSettings.AllowEmailAccounts,
"enforce_multifactor_authentication": *cfg.GuestAccountsSettings.EnforceMultifactorAuthentication,
"isdefault_restrict_creation_to_domains": isDefault(*cfg.GuestAccountsSettings.RestrictCreationToDomains, ""),

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

@@ -3055,6 +3055,7 @@ func (s *DisplaySettings) SetDefaults() {
type GuestAccountsSettings struct {
Enable *bool `access:"authentication_guest_access"`
HideTags *bool `access:"authentication_guest_access"`
AllowEmailAccounts *bool `access:"authentication_guest_access"`
EnforceMultifactorAuthentication *bool `access:"authentication_guest_access"`
RestrictCreationToDomains *string `access:"authentication_guest_access"`
@@ -3065,6 +3066,10 @@ func (s *GuestAccountsSettings) SetDefaults() {
s.Enable = NewBool(false)
}
if s.HideTags == nil {
s.HideTags = NewBool(false)
}
if s.AllowEmailAccounts == nil {
s.AllowEmailAccounts = NewBool(true)
}

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

@@ -5727,6 +5727,16 @@ const AdminDefinition = {
key: 'GuestAccountsSettings.Enable',
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.AUTHENTICATION.GUEST_ACCESS)),
},
{
type: Constants.SettingsTypes.TYPE_BOOL,
key: 'GuestAccountsSettings.HideTags',
label: t('admin.guest_access.hideTags'),
label_default: 'Hide guest tag',
help_text: t('admin.guest_access.hideTagsDescription'),
help_text_default: 'When true, the "guest" tag will not be shown next to the name of all guest users in the Mattermost chat interface.',
help_text_markdown: false,
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.AUTHENTICATION.GUEST_ACCESS)),
},
{
type: Constants.SettingsTypes.TYPE_TEXT,
key: 'GuestAccountsSettings.RestrictCreationToDomains',

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

@@ -46,6 +46,7 @@ describe('components/ChannelHeader', () => {
'minute',
'hour',
],
hideGuestTags: false,
};
const populatedProps = {

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

@@ -95,6 +95,7 @@ export type Props = {
isLastActiveEnabled: boolean;
timestampUnits?: string[];
lastActivityTimestamp?: number;
hideGuestTags: boolean;
};
type State = {
@@ -292,12 +293,13 @@ class ChannelHeader extends React.PureComponent<Props, State> {
rhsState,
hasGuests,
teammateNameDisplaySetting,
hideGuestTags,
} = this.props;
const {formatMessage} = this.props.intl;
const ariaLabelChannelHeader = localizeMessage('accessibility.sections.channelHeader', 'channel header region');
let hasGuestsText: ReactNode = '';
if (hasGuests) {
if (hasGuests && !hideGuestTags) {
hasGuestsText = (
<span className='has-guest-header'>
<span tabIndex={0}>
@@ -399,7 +401,7 @@ class ChannelHeader extends React.PureComponent<Props, State> {
);
});
if (hasGuests) {
if (hasGuests && !hideGuestTags) {
hasGuestsText = (
<span className='has-guest-header'>
<FormattedMessage

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

@@ -116,6 +116,7 @@ function makeMapStateToProps() {
isFileAttachmentsEnabled: isFileAttachmentsEnabled(config),
isLastActiveEnabled,
timestampUnits,
hideGuestTags: config.HideGuestTags === 'true',
};
};
}

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

@@ -25,6 +25,7 @@ import {Channel} from '@mattermost/types/channels';
import {Post} from '@mattermost/types/posts';
import PostMarkdown from './post_markdown';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
export function makeGetMentionKeysForPost(): (
state: GlobalState,
@@ -75,6 +76,7 @@ function makeMapStateToProps() {
mentionKeys: getMentionKeysForPost(state, ownProps.post, channel),
isMilitaryTime: getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false),
timezone: getCurrentTimezone(state),
hideGuestTags: getConfig(state).HideGuestTags === 'true',
};
};
}

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

@@ -23,6 +23,7 @@ describe('components/PostMarkdown', () => {
channelId: 'channel-id',
channel: TestHelper.getChannelMock(),
currentTeam: TestHelper.getTeamMock(),
hideGuestTags: false,
};
const state = {entities: {

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

@@ -66,6 +66,8 @@ type Props = {
*/
isMilitaryTime?: boolean;
timezone?: string;
hideGuestTags: boolean;
}
export default class PostMarkdown extends React.PureComponent<Props> {
@@ -94,6 +96,7 @@ export default class PostMarkdown extends React.PureComponent<Props> {
const renderedSystemMessage = renderSystemMessage(post,
this.props.currentTeam,
this.props.channel,
this.props.hideGuestTags,
this.props.isUserCanManageMembers,
this.props.isMilitaryTime,
this.props.timezone);

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

@@ -50,7 +50,10 @@ function renderJoinChannelMessage(post: Post): ReactNode {
);
}
function renderGuestJoinChannelMessage(post: Post): ReactNode {
function renderGuestJoinChannelMessage(post: Post, hideGuestTags: boolean): ReactNode {
if (hideGuestTags) {
return renderJoinChannelMessage(post);
}
const username = renderUsername(post.props.username);
return (
@@ -90,7 +93,10 @@ function renderAddToChannelMessage(post: Post): ReactNode {
);
}
function renderAddGuestToChannelMessage(post: Post): ReactNode {
function renderAddGuestToChannelMessage(post: Post, hideGuestTags: boolean): ReactNode {
if (hideGuestTags) {
return renderAddToChannelMessage(post);
}
const username = renderUsername(post.props.username);
const addedUsername = renderUsername(post.props.addedUsername);
@@ -363,10 +369,9 @@ function renderMeMessage(post: Post): ReactNode {
const systemMessageRenderers = {
[Posts.POST_TYPES.JOIN_CHANNEL]: renderJoinChannelMessage,
[Posts.POST_TYPES.GUEST_JOIN_CHANNEL]: renderGuestJoinChannelMessage,
[Posts.POST_TYPES.LEAVE_CHANNEL]: renderLeaveChannelMessage,
[Posts.POST_TYPES.ADD_TO_CHANNEL]: renderAddToChannelMessage,
[Posts.POST_TYPES.ADD_GUEST_TO_CHANNEL]: renderAddGuestToChannelMessage,
[Posts.POST_TYPES.EPHEMERAL_ADD_TO_CHANNEL]: renderAddToChannelMessage,
[Posts.POST_TYPES.REMOVE_FROM_CHANNEL]: renderRemoveFromChannelMessage,
[Posts.POST_TYPES.JOIN_TEAM]: renderJoinTeamMessage,
[Posts.POST_TYPES.LEAVE_TEAM]: renderLeaveTeamMessage,
@@ -381,7 +386,7 @@ const systemMessageRenderers = {
[Posts.POST_TYPES.ME]: renderMeMessage,
};
export function renderSystemMessage(post: Post, currentTeam: Team, channel: Channel, isUserCanManageMembers?: boolean, isMilitaryTime?: boolean, timezone?: string): ReactNode {
export function renderSystemMessage(post: Post, currentTeam: Team, channel: Channel, hideGuestTags: boolean, isUserCanManageMembers?: boolean, isMilitaryTime?: boolean, timezone?: string): ReactNode {
const isEphemeral = Utils.isPostEphemeral(post);
if (isEphemeral && post.props?.type === Posts.POST_TYPES.REMINDER) {
return renderReminderACKMessage(post, currentTeam, Boolean(isMilitaryTime), timezone);
@@ -405,8 +410,10 @@ export function renderSystemMessage(post: Post, currentTeam: Team, channel: Chan
return null;
} else if (systemMessageRenderers[post.type]) {
return systemMessageRenderers[post.type](post);
} else if (post.type === Posts.POST_TYPES.EPHEMERAL_ADD_TO_CHANNEL) {
return renderAddToChannelMessage(post);
} else if (post.type === Posts.POST_TYPES.GUEST_JOIN_CHANNEL) {
return renderGuestJoinChannelMessage(post, hideGuestTags);
} else if (post.type === Posts.POST_TYPES.ADD_GUEST_TO_CHANNEL) {
return renderAddGuestToChannelMessage(post, hideGuestTags);
} else if (post.type === Posts.POST_TYPES.COMBINED_USER_ACTIVITY) {
const {allUserIds, allUsernames, messageData} = post.props.user_activity;

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

@@ -1,9 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/widgets/tag/GuestTag should match the snapshot 1`] = `
<Memo(Tag)
className="GuestTag test"
size="xs"
text="GUEST"
/>
`;

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

@@ -2,13 +2,18 @@
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import GuestTag from './guest_tag';
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
describe('components/widgets/tag/GuestTag', () => {
test('should match the snapshot', () => {
const wrapper = shallow(<GuestTag className={'test'}/>);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(<GuestTag className={'test'}/>);
screen.getByText('GUEST');
});
test('should not render when hideTags is true', () => {
renderWithIntlAndStore(<GuestTag className={'test'}/>, {entities: {general: {config: {HideGuestTags: 'true'}}}});
expect(() => screen.getByText('GUEST')).toThrow();
});
});

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

@@ -6,6 +6,9 @@ import classNames from 'classnames';
import {useIntl} from 'react-intl';
import Tag, {TagSize} from './tag';
import {useSelector} from 'react-redux';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {GlobalState} from '@mattermost/types/store';
type Props = {
className?: string;
@@ -14,6 +17,12 @@ type Props = {
const GuestTag = ({className = '', size = 'xs'}: Props) => {
const {formatMessage} = useIntl();
const shouldHideTag = useSelector((state: GlobalState) => getConfig(state).HideGuestTags === 'true');
if (shouldHideTag) {
return null;
}
return (
<Tag
className={classNames('GuestTag', className)}

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

@@ -1127,6 +1127,8 @@
"admin.guest_access.disableConfirmWarning": "All current guest account sessions will be revoked, and marked as inactive",
"admin.guest_access.enableDescription": "When true, external guest can be invited to channels within teams. Please see [Permissions Schemes](../user_management/permissions/system_scheme) for which roles can invite guests.",
"admin.guest_access.enableTitle": "Enable Guest Access: ",
"admin.guest_access.hideTags": "Hide guest tag",
"admin.guest_access.hideTagsDescription": "When true, the \"guest\" tag will not be shown next to the name of all guest users in the Mattermost chat interface.",
"admin.guest_access.mfaDescription": "When true, <link>multi-factor authentication</link> for guests is required for login. New guest users will be required to configure MFA on signup. Logged in guest users without MFA configured are redirected to the MFA setup page until configuration is complete.\n \nIf your system has guest users with login methods other than AD/LDAP and email, MFA must be enforced with the authentication provider outside of Mattermost.",
"admin.guest_access.mfaDescriptionMFANotEnabled": "[Multi-factor authentication](./mfa) is currently not enabled.",
"admin.guest_access.mfaDescriptionMFANotEnforced": "[Multi-factor authentication](./mfa) is currently not enforced.",

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

@@ -26,7 +26,7 @@ export const renderWithIntl = (component: React.ReactNode | React.ReactNodeArray
return render(<IntlProvider locale={locale}>{component}</IntlProvider>);
};
export const renderWithIntlAndStore = (component: React.ReactNode | React.ReactNodeArray, initialState: DeepPartial<GlobalState>, locale = 'en') => {
export const renderWithIntlAndStore = (component: React.ReactNode | React.ReactNodeArray, initialState: DeepPartial<GlobalState> = {}, locale = 'en') => {
// We use a redux-mock-store store for testing, but we set up a real store to ensure the initial state is complete
const realStore = configureStore(initialState);

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

@@ -127,6 +127,7 @@ export type ClientConfig = {
GuestAccountsEnforceMultifactorAuthentication: string;
HasImageProxy: string;
HelpLink: string;
HideGuestTags: string;
IosAppDownloadLink: string;
IosLatestVersion: string;
IosMinVersion: string;
@@ -846,6 +847,7 @@ export type DisplaySettings = {
export type GuestAccountsSettings = {
Enable: boolean;
HideTags: boolean;
AllowEmailAccounts: boolean;
EnforceMultifactorAuthentication: boolean;
RestrictCreationToDomains: string;