Commit 147e7336 authored by Phil Hughes's avatar Phil Hughes

Merge branch...

Merge branch '350094-remove-callout-and-replace-with-help-text-for-personal-access-tokens' into 'master'

Update maximum allowable lifetime message for PAT

See merge request gitlab-org/gitlab!81949
parents 6eb89613 5c71c8ad
<script> <script>
import { GlDatepicker, GlFormInput } from '@gitlab/ui'; import { GlDatepicker, GlFormInput, GlFormGroup } from '@gitlab/ui';
import { __ } from '~/locale';
export default { export default {
name: 'ExpiresAtField', name: 'ExpiresAtField',
components: { GlDatepicker, GlFormInput }, i18n: {
label: __('Expiration date'),
},
components: {
GlDatepicker,
GlFormInput,
GlFormGroup,
MaxExpirationDateMessage: () =>
import('ee_component/access_tokens/components/max_expiration_date_message.vue'),
},
props: { props: {
inputAttrs: { inputAttrs: {
type: Object, type: Object,
required: false, required: false,
default: () => ({}), default: () => ({}),
}, },
maxDate: {
type: Date,
required: false,
default: () => null,
},
}, },
data() { data() {
return { return {
...@@ -20,13 +36,18 @@ export default { ...@@ -20,13 +36,18 @@ export default {
</script> </script>
<template> <template>
<gl-datepicker :target="null" :min-date="minDate"> <gl-form-group :label="$options.i18n.label" :label-for="inputAttrs.id">
<gl-form-input <gl-datepicker :target="null" :min-date="minDate" :max-date="maxDate">
v-bind="inputAttrs" <gl-form-input
class="datepicker gl-datepicker-input" v-bind="inputAttrs"
autocomplete="off" class="datepicker gl-datepicker-input"
inputmode="none" autocomplete="off"
data-qa-selector="expiry_date_field" inputmode="none"
/> data-qa-selector="expiry_date_field"
</gl-datepicker> />
</gl-datepicker>
<template #description>
<max-expiration-date-message :max-date="maxDate" />
</template>
</gl-form-group>
</template> </template>
...@@ -17,6 +17,7 @@ export const initExpiresAtField = () => { ...@@ -17,6 +17,7 @@ export const initExpiresAtField = () => {
} }
const { expiresAt: inputAttrs } = parseRailsFormFields(el); const { expiresAt: inputAttrs } = parseRailsFormFields(el);
const { maxDate } = el.dataset;
return new Vue({ return new Vue({
el, el,
...@@ -24,6 +25,7 @@ export const initExpiresAtField = () => { ...@@ -24,6 +25,7 @@ export const initExpiresAtField = () => {
return h(ExpiresAtField, { return h(ExpiresAtField, {
props: { props: {
inputAttrs, inputAttrs,
maxDate: maxDate ? new Date(maxDate) : undefined,
}, },
}); });
}, },
......
...@@ -27,4 +27,10 @@ module AccessTokensHelper ...@@ -27,4 +27,10 @@ module AccessTokensHelper
} }
}.to_json }.to_json
end end
def expires_at_field_data
{}
end
end end
AccessTokensHelper.prepend_mod
...@@ -24,14 +24,9 @@ ...@@ -24,14 +24,9 @@
%span.form-text.text-muted.col-md-12#access_token_help_text= _("For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members.") % { resource_type: resource_type } %span.form-text.text-muted.col-md-12#access_token_help_text= _("For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members.") % { resource_type: resource_type }
.row .row
.form-group.col-md-6 .col
= f.label :expires_at, _('Expiration date'), class: 'label-bold' .js-access-tokens-expires-at{ data: expires_at_field_data }
.input-icon-wrapper = f.text_field :expires_at, class: 'datepicker gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' }
= render_if_exists 'personal_access_tokens/callout_max_personal_access_token_lifetime'
.js-access-tokens-expires-at
= f.text_field :expires_at, class: 'datepicker gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' }
- if resource - if resource
.row .row
......
<script>
import { GlSprintf, GlLink } from '@gitlab/ui';
import { __ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
import { formatDate } from '~/lib/utils/datetime_utility';
export default {
i18n: {
message: __(
'An Administrator has set the maximum expiration date to %{maxDate}. %{helpLinkStart}Learn more%{helpLinkEnd}.',
),
},
components: { GlSprintf, GlLink },
props: {
maxDate: {
type: Date,
required: false,
default: () => null,
},
},
computed: {
formattedMaxDate() {
if (!this.maxDate) {
return '';
}
return formatDate(this.maxDate, 'isoDate');
},
},
methods: { helpPagePath },
};
</script>
<template>
<span v-if="maxDate">
<gl-sprintf :message="$options.i18n.message">
<template #maxDate>{{ formattedMaxDate }}</template>
<template #helpLink="{ content }"
><gl-link
:href="
helpPagePath('user/admin_area/settings/account_and_limit_settings', {
anchor: 'limit-the-lifetime-of-personal-access-tokens',
})
"
target="_blank"
>{{ content }}</gl-link
></template
>
</gl-sprintf>
</span>
</template>
# frozen_string_literal: true
module EE
module AccessTokensHelper
extend ::Gitlab::Utils::Override
override :expires_at_field_data
def expires_at_field_data
{
max_date: personal_access_token_max_expiry_date&.iso8601
}
end
end
end
- return unless personal_access_token_expiration_policy_enabled?
.bs-callout.bs-callout-danger
= _('Maximum lifetime allowable for Personal Access Tokens is active, your expire date must be set before %{maximum_allowable_date}.') % { maximum_allowable_date: personal_access_token_max_expiry_date.to_date }
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MaxExpirationDateMessage when \`maxDate\` is set renders max date expiration message 1`] = `
<span>
An Administrator has set the maximum expiration date to 2022-03-02.
<a
class="gl-link"
href="/help/user/admin_area/settings/account_and_limit_settings#limit-the-lifetime-of-personal-access-tokens"
rel="noopener"
target="_blank"
>
Learn more
</a>
.
</span>
`;
import { mount } from '@vue/test-utils';
import { GlDatepicker } from '@gitlab/ui';
import ExpiresAtField from '~/access_tokens/components/expires_at_field.vue';
import MaxExpirationDateMessage from 'ee/access_tokens/components/max_expiration_date_message.vue';
describe('~/access_tokens/components/expires_at_field', () => {
let wrapper;
const defaultPropsData = {
inputAttrs: {
id: 'personal_access_token_expires_at',
name: 'personal_access_token[expires_at]',
placeholder: 'YYYY-MM-DD',
},
maxDate: new Date('2022-3-2'),
};
const createComponent = (propsData = defaultPropsData) => {
wrapper = mount(ExpiresAtField, {
propsData,
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('renders `MaxExpirationDateMessage` message component', () => {
expect(wrapper.findComponent(MaxExpirationDateMessage).exists()).toBe(true);
});
it('sets `GlDatepicker` `maxDate` prop', () => {
expect(wrapper.findComponent(GlDatepicker).props('maxDate')).toEqual(defaultPropsData.maxDate);
});
});
import MaxExpirationDateMessage from 'ee/access_tokens/components/max_expiration_date_message.vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
describe('MaxExpirationDateMessage', () => {
let wrapper;
const defaultPropsData = {
maxDate: new Date('2022-3-2'),
};
const createComponent = (propsData = defaultPropsData) => {
wrapper = mountExtended(MaxExpirationDateMessage, {
propsData,
});
};
describe('when `maxDate` is set', () => {
beforeEach(() => {
createComponent();
});
it('renders max date expiration message', () => {
expect(wrapper.element).toMatchSnapshot();
});
});
describe('when `maxDate` is not set', () => {
beforeEach(() => {
createComponent({});
});
it('does not render anything', () => {
expect(wrapper.text()).toBe('');
});
});
});
# frozen_string_literal: true
require "spec_helper"
RSpec.describe EE::AccessTokensHelper do
describe '#expires_at_field_data' do
it 'returns expected hash' do
expect(helper).to receive(:personal_access_token_max_expiry_date).and_return(Time.new(2022, 3, 2, 10, 30, 45, 'UTC'))
expect(helper.expires_at_field_data).to eq({
max_date: '2022-03-02T10:30:45Z'
})
end
end
end
...@@ -3702,6 +3702,9 @@ msgstr "" ...@@ -3702,6 +3702,9 @@ msgstr ""
msgid "An %{link_start}alert%{link_end} with the same fingerprint is already open. To change the status of this alert, resolve the linked alert." msgid "An %{link_start}alert%{link_end} with the same fingerprint is already open. To change the status of this alert, resolve the linked alert."
msgstr "" msgstr ""
msgid "An Administrator has set the maximum expiration date to %{maxDate}. %{helpLinkStart}Learn more%{helpLinkEnd}."
msgstr ""
msgid "An Enterprise User GitLab account has been created for you by your organization:" msgid "An Enterprise User GitLab account has been created for you by your organization:"
msgstr "" msgstr ""
...@@ -22659,9 +22662,6 @@ msgstr "" ...@@ -22659,9 +22662,6 @@ msgstr ""
msgid "Maximum job timeout has a value which could not be accepted" msgid "Maximum job timeout has a value which could not be accepted"
msgstr "" msgstr ""
msgid "Maximum lifetime allowable for Personal Access Tokens is active, your expire date must be set before %{maximum_allowable_date}."
msgstr ""
msgid "Maximum lines in a diff" msgid "Maximum lines in a diff"
msgstr "" msgstr ""
......
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`~/access_tokens/components/expires_at_field should render datepicker with input info 1`] = ` exports[`~/access_tokens/components/expires_at_field should render datepicker with input info 1`] = `
<gl-datepicker-stub <gl-form-group-stub
ariallabel="" label="Expiration date"
autocomplete="" label-for="personal_access_token_expires_at"
container="" labeldescription=""
displayfield="true" optionaltext="(optional)"
firstday="0"
inputlabel="Enter date"
mindate="Mon Jul 06 2020 00:00:00 GMT+0000 (Greenwich Mean Time)"
placeholder="YYYY-MM-DD"
theme=""
> >
<gl-form-input-stub <gl-datepicker-stub
autocomplete="off" ariallabel=""
class="datepicker gl-datepicker-input" autocomplete=""
data-qa-selector="expiry_date_field" container=""
id="personal_access_token_expires_at" displayfield="true"
inputmode="none" firstday="0"
name="personal_access_token[expires_at]" inputlabel="Enter date"
mindate="Mon Jul 06 2020 00:00:00 GMT+0000 (Greenwich Mean Time)"
placeholder="YYYY-MM-DD" placeholder="YYYY-MM-DD"
/> theme=""
</gl-datepicker-stub> >
<gl-form-input-stub
autocomplete="off"
class="datepicker gl-datepicker-input"
data-qa-selector="expiry_date_field"
id="personal_access_token_expires_at"
inputmode="none"
name="personal_access_token[expires_at]"
placeholder="YYYY-MM-DD"
/>
</gl-datepicker-stub>
</gl-form-group-stub>
`; `;
...@@ -4,15 +4,17 @@ import ExpiresAtField from '~/access_tokens/components/expires_at_field.vue'; ...@@ -4,15 +4,17 @@ import ExpiresAtField from '~/access_tokens/components/expires_at_field.vue';
describe('~/access_tokens/components/expires_at_field', () => { describe('~/access_tokens/components/expires_at_field', () => {
let wrapper; let wrapper;
const createComponent = () => { const defaultPropsData = {
inputAttrs: {
id: 'personal_access_token_expires_at',
name: 'personal_access_token[expires_at]',
placeholder: 'YYYY-MM-DD',
},
};
const createComponent = (propsData = defaultPropsData) => {
wrapper = shallowMount(ExpiresAtField, { wrapper = shallowMount(ExpiresAtField, {
propsData: { propsData,
inputAttrs: {
id: 'personal_access_token_expires_at',
name: 'personal_access_token[expires_at]',
placeholder: 'YYYY-MM-DD',
},
},
}); });
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment