Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
208f195a9b
commit
dca8df0c90
|
|
@ -800,7 +800,6 @@ RSpec/ContextWording:
|
|||
- 'ee/spec/services/projects/operations/update_service_spec.rb'
|
||||
- 'ee/spec/services/projects/protect_default_branch_service_spec.rb'
|
||||
- 'ee/spec/services/projects/restore_service_spec.rb'
|
||||
- 'ee/spec/services/projects/slack_application_install_service_spec.rb'
|
||||
- 'ee/spec/services/projects/transfer_service_spec.rb'
|
||||
- 'ee/spec/services/projects/update_mirror_service_spec.rb'
|
||||
- 'ee/spec/services/projects/update_service_spec.rb'
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ RSpec/ExpectInHook:
|
|||
- 'ee/spec/controllers/ee/projects/merge_requests/content_controller_spec.rb'
|
||||
- 'ee/spec/controllers/groups/analytics/productivity_analytics_controller_spec.rb'
|
||||
- 'ee/spec/controllers/groups/seat_usage_controller_spec.rb'
|
||||
- 'ee/spec/controllers/projects/settings/slacks_controller_spec.rb'
|
||||
- 'ee/spec/controllers/subscriptions_controller_spec.rb'
|
||||
- 'ee/spec/elastic/migrate/20220118150500_delete_orphaned_commits_spec.rb'
|
||||
- 'ee/spec/elastic/migrate/20220119120500_populate_commit_permissions_in_main_index_spec.rb'
|
||||
|
|
|
|||
|
|
@ -412,7 +412,6 @@ Style/ClassAndModuleChildren:
|
|||
- 'ee/app/controllers/groups/wikis_controller.rb'
|
||||
- 'ee/app/controllers/oauth/geo_auth_controller.rb'
|
||||
- 'ee/app/controllers/profiles/billings_controller.rb'
|
||||
- 'ee/app/controllers/profiles/slacks_controller.rb'
|
||||
- 'ee/app/controllers/projects/analytics/issues_analytics_controller.rb'
|
||||
- 'ee/app/controllers/projects/analytics/merge_request_analytics_controller.rb'
|
||||
- 'ee/app/controllers/projects/approver_groups_controller.rb'
|
||||
|
|
|
|||
|
|
@ -94,7 +94,6 @@ Style/EmptyMethod:
|
|||
- 'ee/app/controllers/projects/security/dast_scanner_profiles_controller.rb'
|
||||
- 'ee/app/controllers/projects/security/dast_site_profiles_controller.rb'
|
||||
- 'ee/app/controllers/projects/security/sast_configuration_controller.rb'
|
||||
- 'ee/app/controllers/projects/settings/slacks_controller.rb'
|
||||
- 'ee/app/controllers/subscriptions/groups_controller.rb'
|
||||
- 'ee/app/models/ee/epic.rb'
|
||||
- 'ee/app/services/feature_flag_issues/destroy_service.rb'
|
||||
|
|
|
|||
|
|
@ -274,7 +274,6 @@ Style/GuardClause:
|
|||
- 'ee/app/controllers/profiles/billings_controller.rb'
|
||||
- 'ee/app/controllers/projects/path_locks_controller.rb'
|
||||
- 'ee/app/controllers/projects/security/policies_controller.rb'
|
||||
- 'ee/app/controllers/projects/settings/slacks_controller.rb'
|
||||
- 'ee/app/controllers/smartcard_controller.rb'
|
||||
- 'ee/app/finders/ee/template_finder.rb'
|
||||
- 'ee/app/finders/iterations_finder.rb'
|
||||
|
|
|
|||
|
|
@ -411,7 +411,6 @@ Style/IfUnlessModifier:
|
|||
- 'ee/app/controllers/projects/integrations/zentao/issues_controller.rb'
|
||||
- 'ee/app/controllers/projects/path_locks_controller.rb'
|
||||
- 'ee/app/controllers/projects/push_rules_controller.rb'
|
||||
- 'ee/app/controllers/projects/settings/slacks_controller.rb'
|
||||
- 'ee/app/finders/security/pipeline_vulnerabilities_finder.rb'
|
||||
- 'ee/app/finders/security/vulnerabilities_finder.rb'
|
||||
- 'ee/app/graphql/mutations/audit_events/external_audit_event_destinations/create.rb'
|
||||
|
|
|
|||
|
|
@ -133,8 +133,3 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.gl-spinner-container {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import { withGitLabAPIAccess } from 'storybook_addons/gitlab_api_access';
|
||||
import Api from '~/api';
|
||||
import { ContentEditor } from './index';
|
||||
|
||||
export default {
|
||||
component: ContentEditor,
|
||||
title: 'ce/content_editor/content_editor',
|
||||
decorators: [withGitLabAPIAccess],
|
||||
};
|
||||
|
||||
const Template = (_, { argTypes }) => ({
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Profiles
|
||||
class SlacksController < Profiles::ApplicationController
|
||||
include IntegrationsHelper
|
||||
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
layout 'application'
|
||||
|
||||
feature_category :integrations
|
||||
|
||||
def edit
|
||||
@projects = disabled_projects.inc_routes if current_user
|
||||
end
|
||||
|
||||
def slack_link
|
||||
project = disabled_projects.find(params[:project_id])
|
||||
link = add_to_slack_link(project, Gitlab::CurrentSettings.slack_app_id)
|
||||
|
||||
render json: { add_to_slack_link: link }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def disabled_projects
|
||||
@disabled_projects ||= current_user
|
||||
.authorized_projects(Gitlab::Access::MAINTAINER)
|
||||
.with_slack_application_disabled
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Projects
|
||||
module Settings
|
||||
class SlacksController < Projects::ApplicationController
|
||||
before_action :handle_oauth_error, only: :slack_auth
|
||||
before_action :check_oauth_state, only: :slack_auth
|
||||
before_action :authorize_admin_project!
|
||||
before_action :slack_integration, only: [:edit, :update]
|
||||
before_action :service, only: [:destroy, :edit, :update]
|
||||
|
||||
layout 'project_settings'
|
||||
|
||||
feature_category :integrations
|
||||
|
||||
def slack_auth
|
||||
result = Projects::SlackApplicationInstallService.new(project, current_user, params).execute
|
||||
|
||||
flash[:alert] = result[:message] if result[:status] == :error
|
||||
|
||||
session[:slack_install_success] = true
|
||||
redirect_to_service_page
|
||||
end
|
||||
|
||||
def destroy
|
||||
slack_integration.destroy
|
||||
|
||||
redirect_to_service_page
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def update
|
||||
if slack_integration.update(slack_integration_params)
|
||||
flash[:notice] = 'The project alias was updated successfully'
|
||||
|
||||
redirect_to_service_page
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redirect_to_service_page
|
||||
redirect_to edit_project_settings_integration_path(
|
||||
project,
|
||||
project.gitlab_slack_application_integration || project.build_gitlab_slack_application_integration
|
||||
)
|
||||
end
|
||||
|
||||
def check_oauth_state
|
||||
render_403 unless valid_authenticity_token?(session, params[:state])
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def handle_oauth_error
|
||||
return unless params[:error] == 'access_denied'
|
||||
|
||||
flash[:alert] = 'Access denied'
|
||||
redirect_to_service_page
|
||||
end
|
||||
|
||||
def slack_integration
|
||||
@slack_integration ||= project.gitlab_slack_application_integration.slack_integration
|
||||
end
|
||||
|
||||
def service
|
||||
@service = project.gitlab_slack_application_integration
|
||||
end
|
||||
|
||||
def slack_integration_params
|
||||
params.require(:slack_integration).permit(:alias)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -136,6 +136,11 @@ module IntegrationsHelper
|
|||
form_data[:jira_issue_transition_id] = integration.jira_issue_transition_id
|
||||
end
|
||||
|
||||
if integration.is_a?(::Integrations::GitlabSlackApplication)
|
||||
form_data[:upgrade_slack_url] = add_to_slack_link(project, slack_app_id)
|
||||
form_data[:should_upgrade_slack] = integration.upgrade_needed?.to_s
|
||||
end
|
||||
|
||||
form_data
|
||||
end
|
||||
|
||||
|
|
@ -212,6 +217,28 @@ module IntegrationsHelper
|
|||
event_i18n_map[event] || event.to_s.humanize
|
||||
end
|
||||
|
||||
def add_to_slack_link(project, slack_app_id)
|
||||
query = {
|
||||
scope: SlackIntegration::SCOPES.join(','),
|
||||
client_id: slack_app_id,
|
||||
redirect_uri: slack_auth_project_settings_slack_url(project),
|
||||
state: form_authenticity_token
|
||||
}
|
||||
|
||||
"#{::Projects::SlackApplicationInstallService::SLACK_AUTHORIZE_URL}?#{query.to_query}"
|
||||
end
|
||||
|
||||
def gitlab_slack_application_data(projects)
|
||||
{
|
||||
projects: (projects || []).to_json(only: [:id, :name], methods: [:avatar_url, :name_with_namespace]),
|
||||
sign_in_path: new_session_path(:user, redirect_to_referer: 'yes'),
|
||||
is_signed_in: current_user.present?.to_s,
|
||||
slack_link_path: slack_link_profile_slack_path,
|
||||
gitlab_logo_path: image_path('illustrations/gitlab_logo.svg'),
|
||||
slack_logo_path: image_path('illustrations/slack_logo.svg')
|
||||
}
|
||||
end
|
||||
|
||||
extend self
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -2279,6 +2279,14 @@ class User < ApplicationRecord
|
|||
abuse_trust_scores.telesign.order(created_at: :desc).first&.score || 0.0
|
||||
end
|
||||
|
||||
def arkose_global_score
|
||||
abuse_trust_scores.arkose_global_score.order(created_at: :desc).first&.score || 0.0
|
||||
end
|
||||
|
||||
def arkose_custom_score
|
||||
abuse_trust_scores.arkose_custom_score.order(created_at: :desc).first&.score || 0.0
|
||||
end
|
||||
|
||||
def trust_scores_for_source(source)
|
||||
abuse_trust_scores.where(source: source)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Projects
|
||||
class SlackApplicationInstallService < BaseService
|
||||
include Gitlab::Routing
|
||||
|
||||
# Endpoint to initiate the OAuth flow, redirects to Slack's authorization screen
|
||||
# https://api.slack.com/authentication/oauth-v2#asking
|
||||
SLACK_AUTHORIZE_URL = 'https://slack.com/oauth/v2/authorize'
|
||||
|
||||
# Endpoint to exchange the temporary authorization code for an access token
|
||||
# https://api.slack.com/authentication/oauth-v2#exchanging
|
||||
SLACK_EXCHANGE_TOKEN_URL = 'https://slack.com/api/oauth.v2.access'
|
||||
|
||||
def execute
|
||||
slack_data = exchange_slack_token
|
||||
|
||||
return error("Slack: #{slack_data['error']}") unless slack_data['ok']
|
||||
|
||||
integration = project.gitlab_slack_application_integration \
|
||||
|| project.create_gitlab_slack_application_integration!
|
||||
|
||||
installation = integration.slack_integration || integration.build_slack_integration
|
||||
|
||||
installation.update!(
|
||||
bot_user_id: slack_data['bot_user_id'],
|
||||
bot_access_token: slack_data['access_token'],
|
||||
team_id: slack_data.dig('team', 'id'),
|
||||
team_name: slack_data.dig('team', 'name'),
|
||||
alias: project.full_path,
|
||||
user_id: slack_data.dig('authed_user', 'id'),
|
||||
authorized_scope_names: slack_data['scope']
|
||||
)
|
||||
|
||||
update_legacy_installations!(installation)
|
||||
|
||||
success
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def exchange_slack_token
|
||||
query = {
|
||||
client_id: Gitlab::CurrentSettings.slack_app_id,
|
||||
client_secret: Gitlab::CurrentSettings.slack_app_secret,
|
||||
code: params[:code],
|
||||
# NOTE: Needs to match the `redirect_uri` passed to the authorization endpoint,
|
||||
# otherwise we get a `bad_redirect_uri` error.
|
||||
redirect_uri: slack_auth_project_settings_slack_url(project)
|
||||
}
|
||||
|
||||
Gitlab::HTTP.get(SLACK_EXCHANGE_TOKEN_URL, query: query).to_hash
|
||||
end
|
||||
|
||||
# Update any legacy SlackIntegration records for the Slack Workspace. Legacy SlackIntegration records
|
||||
# are any created before our Slack App was upgraded to use Granular Bot Permissions and issue a
|
||||
# bot_access_token. Any SlackIntegration records for the Slack Workspace will already have the same
|
||||
# bot_access_token.
|
||||
def update_legacy_installations!(installation)
|
||||
updatable_attributes = installation.attributes.slice(
|
||||
'user_id',
|
||||
'bot_user_id',
|
||||
'encrypted_bot_access_token',
|
||||
'encrypted_bot_access_token_iv',
|
||||
'updated_at'
|
||||
)
|
||||
|
||||
SlackIntegration.by_team(installation.team_id).id_not_in(installation.id).each_batch do |batch|
|
||||
batch_ids = batch.pluck(:id) # rubocop: disable CodeReuse/ActiveRecord
|
||||
batch.update_all(updatable_attributes)
|
||||
|
||||
::Integrations::SlackWorkspace::IntegrationApiScope.update_scopes(batch_ids, installation.slack_api_scopes)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
- add_to_breadcrumbs _('Profile'), profile_path
|
||||
- @hide_top_links = true
|
||||
- @content_class = 'limit-container-width'
|
||||
- page_title s_('SlackIntegration|GitLab for Slack')
|
||||
|
||||
.js-gitlab-slack-application{ data: gitlab_slack_application_data(@projects) }
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
- page_title _('Edit Slack integration')
|
||||
|
||||
.row.gl-mt-3.gl-mb-3
|
||||
.col-lg-3
|
||||
%h4.gl-mt-0
|
||||
= s_('Integrations|Edit project alias')
|
||||
|
||||
%p= s_('Integrations|You can use this alias in your Slack commands')
|
||||
.col-lg-9
|
||||
= form_errors(@slack_integration)
|
||||
= form_for(@slack_integration, url: project_settings_slack_path(@project), method: :put, html: { class: 'gl-show-field-errors js-integration-settings-form'}) do |form|
|
||||
.form-group.row
|
||||
= form.label :alias, s_('Integrations|Enter your alias'), class: 'col-form-label'
|
||||
.col-sm-10
|
||||
= form.text_field :alias, class: 'form-control', placeholder: @slack_integration.alias, required: true
|
||||
|
||||
.footer-block.row-content-block
|
||||
= form.submit _('Save changes'), pajamas_button: true
|
||||
|
||||
= link_to _('Cancel'), edit_project_settings_integration_path(@project, @service), class: 'btn gl-button btn-cancel'
|
||||
|
|
@ -39,6 +39,13 @@ resource :profile, only: [:show, :update] do
|
|||
put :reset
|
||||
end
|
||||
end
|
||||
|
||||
resource :slack, only: [:edit] do
|
||||
member do
|
||||
get :slack_link
|
||||
end
|
||||
end
|
||||
|
||||
resource :preferences, only: [:show, :update]
|
||||
|
||||
resources :comment_templates, only: [:index, :show], action: :index
|
||||
|
|
|
|||
|
|
@ -144,6 +144,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
|
|||
end
|
||||
end
|
||||
|
||||
resource :slack, only: [:destroy, :edit, :update] do
|
||||
get :slack_auth
|
||||
end
|
||||
|
||||
resource :repository, only: [:show, :update], controller: :repository do
|
||||
# TODO: Removed this "create_deploy_token" route after change was made in app/helpers/ci_variables_helper.rb:14
|
||||
# See MR comment for more detail: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27059#note_311585356
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ const alias = {
|
|||
test_fixtures_static: path.join(ROOT_PATH, 'spec/frontend/fixtures/static'),
|
||||
test_helpers: path.join(ROOT_PATH, 'spec/frontend_integration/test_helpers'),
|
||||
public: path.join(ROOT_PATH, 'public'),
|
||||
storybook_addons: path.resolve(ROOT_PATH, 'storybook/config/addons'),
|
||||
};
|
||||
|
||||
if (IS_EE) {
|
||||
|
|
|
|||
|
|
@ -1747,7 +1747,7 @@ If the above steps are **not successful**, proceed through the next steps:
|
|||
|
||||
If different operating systems or different operating system versions are deployed across Geo sites, you should perform a locale data compatibility check before setting up Geo.
|
||||
|
||||
Geo uses PostgreSQL and Streaming Replication to replicate data across Geo sites. PostgreSQL uses locale data provided by the operating system's C library for sorting text. If the locale data in the C library is incompatible across Geo sites, erroneous query results that lead to [incorrect behavior on secondary sites](https://gitlab.com/gitlab-org/gitlab/-/issues/360723).
|
||||
Geo uses PostgreSQL and Streaming Replication to replicate data across Geo sites. PostgreSQL uses locale data provided by the operating system's C library for sorting text. If the locale data in the C library is incompatible across Geo sites, it can cause erroneous query results that lead to [incorrect behavior on secondary sites](https://gitlab.com/gitlab-org/gitlab/-/issues/360723).
|
||||
|
||||
For example, Ubuntu 18.04 (and earlier) and RHEL/Centos7 (and earlier) are incompatible with their later releases.
|
||||
See the [PostgreSQL wiki for more details](https://wiki.postgresql.org/wiki/Locale_data_changes).
|
||||
|
|
|
|||
|
|
@ -65,9 +65,9 @@ This section documents the current behavior of GitLab when Silent Mode is enable
|
|||
|
||||
Incoming emails still raise issues, but the users who sent the emails to [Service Desk](../../user/project/service_desk.md) are not notified of issue creation or comments on their issues.
|
||||
|
||||
### Project and group webhooks
|
||||
### Webhooks
|
||||
|
||||
Project and group webhooks are suppressed. The relevant Sidekiq jobs fail 4 times and then disappear, while Silent Mode is enabled. [Issue 393639](https://gitlab.com/gitlab-org/gitlab/-/issues/393639) discusses preventing the Sidekiq jobs from running in the first place.
|
||||
[Project and group webhooks](../../user/project/integrations/webhooks.md), and [system hooks](../system_hooks.md) are suppressed. The relevant Sidekiq jobs fail 4 times and then disappear, while Silent Mode is enabled. [Issue 393639](https://gitlab.com/gitlab-org/gitlab/-/issues/393639) discusses preventing the Sidekiq jobs from running in the first place.
|
||||
|
||||
Triggering webhook tests via the UI results in HTTP status 500 responses.
|
||||
|
||||
|
|
|
|||
|
|
@ -2219,13 +2219,14 @@ Returns:
|
|||
- `403 Forbidden` if not authenticated as an administrator.
|
||||
- `404 User Not Found` if user cannot be found.
|
||||
|
||||
## Create a runner **(FREE SELF)**
|
||||
## Create a runner **(FREE)**
|
||||
|
||||
Creates a runner linked to the current user.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator or have the Owner role of the target namespace or project.
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
|
||||
Be sure to copy or save the `token` in the response, the value cannot be retrieved again.
|
||||
|
||||
|
|
|
|||
|
|
@ -78,12 +78,29 @@ a starting point.
|
|||
|
||||
You can also use the GitLab API Access panel in the Storybook UI to set the GitLab instance URL and access token.
|
||||
|
||||
### Using REST API
|
||||
### Set up API access in your stories
|
||||
|
||||
You should apply the `withGitLabAPIAccess` decorator to the stories that will consume GitLab’s APIs. This decorator
|
||||
will display a badge indicating that the story won't work without providing the API access parameters:
|
||||
|
||||
```javascript
|
||||
import { withGitLabAPIAccess } from 'storybook_addons/gitlab_api_access';
|
||||
import Api from '~/api';
|
||||
import { ContentEditor } from './index';
|
||||
|
||||
export default {
|
||||
component: ContentEditor,
|
||||
title: 'ce/content_editor/content_editor',
|
||||
decorators: [withGitLabAPIAccess],
|
||||
};
|
||||
```
|
||||
|
||||
#### Using REST API
|
||||
|
||||
The Storybook sets up `~/lib/utils/axios_utils` in `storybook/config/preview.js`. Components that use the REST API
|
||||
should work out of the box as long as you provide a valid GitLab instance URL and access token.
|
||||
|
||||
### Using GraphQL
|
||||
#### Using GraphQL
|
||||
|
||||
To write a story for a component that uses the GraphQL API, use the `createVueApollo` method provided in
|
||||
the Story context.
|
||||
|
|
@ -91,6 +108,7 @@ the Story context.
|
|||
```javascript
|
||||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { withGitLabAPIAccess } from 'storybook_addons/gitlab_api_access';
|
||||
import WorkspacesList from './list.vue';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
|
@ -99,6 +117,9 @@ const Template = (_, { argTypes, createVueApollo }) => {
|
|||
return {
|
||||
components: { WorkspacesList },
|
||||
apolloProvider: createVueApollo(),
|
||||
provide: {
|
||||
emptyStateSvgPath: '',
|
||||
},
|
||||
props: Object.keys(argTypes),
|
||||
template: '<workspaces-list />',
|
||||
};
|
||||
|
|
@ -107,10 +128,10 @@ const Template = (_, { argTypes, createVueApollo }) => {
|
|||
export default {
|
||||
component: WorkspacesList,
|
||||
title: 'ee/remote_development/workspaces_list',
|
||||
decorators: [withGitLabAPIAccess],
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
||||
Default.args = {};
|
||||
|
||||
```
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB |
|
|
@ -31,6 +31,11 @@ in that row:
|
|||
- False positive **{false-positive}**: The scanner determined this vulnerability to be a false
|
||||
positive.
|
||||
|
||||
To open an issue created for a vulnerability, hover over the **Activity** entry, then select the link.
|
||||
The issue icon (**{issues}**) indicates the issue's status. If Jira issue support is enabled, the
|
||||
issue link found in the **Activity** entry links out to the issue in Jira. Unlike GitLab issues, the
|
||||
status of a Jira issue is not shown in the GitLab UI.
|
||||
|
||||

|
||||
|
||||
## Project-level Vulnerability Report
|
||||
|
|
@ -57,7 +62,6 @@ From the Vulnerability Report you can:
|
|||
- [Filter the list of vulnerabilities](#filter-the-list-of-vulnerabilities).
|
||||
- [View more details about a vulnerability](#view-details-of-a-vulnerability).
|
||||
- [View vulnerable source location](#view-vulnerable-source-location) (if available).
|
||||
- [View an issue raised for a vulnerability](#view-issues-raised-for-a-vulnerability).
|
||||
- [Change the status of vulnerabilities](#change-status-of-vulnerabilities).
|
||||
- [Export details of vulnerabilities](#export-vulnerability-details).
|
||||
- [Sort vulnerabilities by date](#sort-vulnerabilities-by-date-detected).
|
||||
|
|
@ -151,15 +155,6 @@ in the default branch.
|
|||
|
||||
To view the relevant file, select the filename in the vulnerability's details.
|
||||
|
||||
## View issues raised for a vulnerability
|
||||
|
||||
The **Activity** column indicates the number of issues that have been created for the vulnerability.
|
||||
Hover over an **Activity** entry and select a link go to that issue. The status of whether the issue is open or closed also displays in the hover menu.
|
||||
|
||||

|
||||
|
||||
If Jira issue support is enabled, the issue link found in the Activity entry links out to the issue in Jira. Unlike GitLab issues, the status of whether a Jira issue is Open or Closed does not display in the GitLab UI.
|
||||
|
||||
## Change status of vulnerabilities
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292636) in GitLab 13.10, all statuses became selectable.
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ module API
|
|||
helpers do
|
||||
# EE::API::Projects would override this method
|
||||
def apply_filters(projects)
|
||||
projects = projects.with_issues_available_for_user(current_user) if params[:with_issues_enabled]
|
||||
projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled]
|
||||
projects = projects.with_statistics if params[:statistics]
|
||||
projects = projects.joins(:statistics) if params[:order_by].include?('project_statistics') # rubocop: disable CodeReuse/ActiveRecord
|
||||
projects = projects.created_by(current_user).imported.with_import_state if params[:imported]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Profiles::SlacksController, feature_category: :integrations do
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
|
||||
allow(subject).to receive(:current_user).and_return(user)
|
||||
end
|
||||
|
||||
describe 'GET edit' do
|
||||
before do
|
||||
get :edit
|
||||
end
|
||||
|
||||
it 'renders' do
|
||||
expect(response).to render_template :edit
|
||||
end
|
||||
|
||||
it 'assigns projects' do
|
||||
expect(assigns[:projects]).to eq []
|
||||
end
|
||||
|
||||
it 'assigns disabled_projects' do
|
||||
expect(assigns[:disabled_projects]).to eq []
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET slack_link' do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
context 'when user is not a maintainer of the project' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it 'renders 404' do
|
||||
get :slack_link, params: { project_id: project.id }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
expect(response.body).to be_blank
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a maintainer of the project' do
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
end
|
||||
|
||||
it 'renders slack link' do
|
||||
allow(controller).to receive(:add_to_slack_link).and_return('mock_redirect_link')
|
||||
|
||||
get :slack_link, params: { project_id: project.id }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response).to eq({ 'add_to_slack_link' => 'mock_redirect_link' })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Projects::Settings::SlacksController, feature_category: :integrations do
|
||||
let_it_be_with_refind(:project) { create(:project, :public) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
def redirect_url(project)
|
||||
edit_project_settings_integration_path(
|
||||
project,
|
||||
Integrations::GitlabSlackApplication.to_param
|
||||
)
|
||||
end
|
||||
|
||||
describe 'GET slack_auth' do
|
||||
def stub_service(result)
|
||||
service = double
|
||||
expect(service).to receive(:execute).and_return(result)
|
||||
expect(Projects::SlackApplicationInstallService)
|
||||
.to receive(:new).with(project, user, anything).and_return(service)
|
||||
end
|
||||
|
||||
context 'when valid CSRF token is provided' do
|
||||
before do
|
||||
allow(controller).to receive(:check_oauth_state).and_return(true)
|
||||
end
|
||||
|
||||
it 'calls service and redirects with no alerts if result is successful' do
|
||||
stub_service(status: :success)
|
||||
|
||||
get :slack_auth, params: { namespace_id: project.namespace, project_id: project }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:found)
|
||||
expect(response).to redirect_to(redirect_url(project))
|
||||
expect(flash[:alert]).to be_nil
|
||||
expect(session[:slack_install_success]).to be(true)
|
||||
end
|
||||
|
||||
it 'calls service and redirects with the alert if there is error' do
|
||||
stub_service(status: :error, message: 'error')
|
||||
|
||||
get :slack_auth, params: { namespace_id: project.namespace, project_id: project }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:found)
|
||||
expect(response).to redirect_to(redirect_url(project))
|
||||
expect(flash[:alert]).to eq('error')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no CSRF token is provided' do
|
||||
it 'returns 403' do
|
||||
get :slack_auth, params: { namespace_id: project.namespace, project_id: project }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there was an OAuth error' do
|
||||
it 'redirects with an alert' do
|
||||
get :slack_auth, params: { namespace_id: project.namespace, project_id: project, error: 'access_denied' }
|
||||
|
||||
expect(flash[:alert]).to eq('Access denied')
|
||||
expect(response).to have_gitlab_http_status(:found)
|
||||
expect(response).to redirect_to(redirect_url(project))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST update' do
|
||||
let_it_be(:integration) { create(:gitlab_slack_application_integration, project: project) }
|
||||
|
||||
let(:params) do
|
||||
{ namespace_id: project.namespace, project_id: project, slack_integration: { alias: new_alias } }
|
||||
end
|
||||
|
||||
context 'when alias is valid' do
|
||||
let(:new_alias) { 'foo' }
|
||||
|
||||
it 'updates the record' do
|
||||
expect do
|
||||
post :update, params: params
|
||||
end.to change { integration.reload.slack_integration.alias }.to(new_alias)
|
||||
expect(response).to have_gitlab_http_status(:found)
|
||||
expect(response).to redirect_to(redirect_url(project))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when alias is invalid' do
|
||||
let(:new_alias) { '' }
|
||||
|
||||
it 'does not update the record' do
|
||||
expect do
|
||||
post :update, params: params
|
||||
end.not_to change { integration.reload.slack_integration.alias }
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to render_template('projects/settings/slacks/edit')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE destroy' do
|
||||
it 'destroys the record' do
|
||||
create(:gitlab_slack_application_integration, project: project)
|
||||
|
||||
expect do
|
||||
delete :destroy, params: { namespace_id: project.namespace, project_id: project }
|
||||
end.to change { project.gitlab_slack_application_integration.reload.slack_integration }.to(nil)
|
||||
expect(response).to have_gitlab_http_status(:found)
|
||||
expect(response).to redirect_to(redirect_url(project))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe IntegrationsHelper do
|
||||
RSpec.describe IntegrationsHelper, feature_category: :integrations do
|
||||
let_it_be_with_refind(:project) { create(:project) }
|
||||
|
||||
shared_examples 'is defined for each integration event' do
|
||||
Integration.available_integration_names.each do |integration|
|
||||
events = Integration.integration_name_to_model(integration).new.configurable_events
|
||||
|
|
@ -84,13 +86,60 @@ RSpec.describe IntegrationsHelper do
|
|||
]
|
||||
end
|
||||
|
||||
let(:slack_app_fields) do
|
||||
[
|
||||
:upgrade_slack_url,
|
||||
:should_upgrade_slack
|
||||
]
|
||||
end
|
||||
|
||||
subject { helper.integration_form_data(integration) }
|
||||
|
||||
context 'with Slack integration' do
|
||||
let(:integration) { build(:integrations_slack) }
|
||||
context 'with a GitLab for Slack App integration' do
|
||||
let(:integration) { build(:gitlab_slack_application_integration, project: project) }
|
||||
|
||||
let(:redirect_url) do
|
||||
"http://test.host/#{project.full_path}/-/settings/slack/slack_auth"
|
||||
end
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:slack_auth_project_settings_slack_url).and_return(redirect_url)
|
||||
end
|
||||
|
||||
it { is_expected.to include(*fields, *slack_app_fields) }
|
||||
it { is_expected.not_to include(*jira_fields) }
|
||||
|
||||
it 'includes app upgrade URL' do
|
||||
stub_application_setting(slack_app_id: 'MOCK_APP_ID')
|
||||
|
||||
expect(subject[:upgrade_slack_url]).to start_with(
|
||||
[
|
||||
Projects::SlackApplicationInstallService::SLACK_AUTHORIZE_URL,
|
||||
'?client_id=MOCK_APP_ID',
|
||||
"&redirect_uri=#{CGI.escape(redirect_url)}"
|
||||
].join
|
||||
)
|
||||
end
|
||||
|
||||
it 'includes the flag to upgrade Slack app, set to true' do
|
||||
expect(subject[:should_upgrade_slack]).to eq 'true'
|
||||
end
|
||||
|
||||
context 'when the integration includes all necessary scopes' do
|
||||
let(:integration) { create(:gitlab_slack_application_integration, :all_features_supported, project: project) }
|
||||
|
||||
it 'includes the flag to upgrade Slack app, set to false' do
|
||||
expect(subject[:should_upgrade_slack]).to eq 'false'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with Jenkins integration' do
|
||||
let(:integration) { build(:jenkins_integration) }
|
||||
|
||||
it { is_expected.to include(*fields) }
|
||||
it { is_expected.not_to include(*jira_fields) }
|
||||
it { is_expected.not_to include(*slack_app_fields) }
|
||||
|
||||
specify do
|
||||
expect(subject[:reset_path]).to eq(helper.scoped_reset_integration_path(integration))
|
||||
|
|
@ -101,10 +150,11 @@ RSpec.describe IntegrationsHelper do
|
|||
end
|
||||
end
|
||||
|
||||
context 'Jira service' do
|
||||
context 'with Jira integration' do
|
||||
let(:integration) { build(:jira_integration) }
|
||||
|
||||
it { is_expected.to include(*fields, *jira_fields) }
|
||||
it { is_expected.not_to include(*slack_app_fields) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -151,6 +201,66 @@ RSpec.describe IntegrationsHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#add_to_slack_link' do
|
||||
let(:slack_link) { helper.add_to_slack_link(project, 'A12345') }
|
||||
let(:query) { Rack::Utils.parse_query(URI.parse(slack_link).query) }
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:form_authenticity_token).and_return('a token')
|
||||
allow(helper).to receive(:slack_auth_project_settings_slack_url).and_return('http://redirect')
|
||||
end
|
||||
|
||||
it 'returns the endpoint URL with all needed params' do
|
||||
expect(slack_link).to start_with(Projects::SlackApplicationInstallService::SLACK_AUTHORIZE_URL)
|
||||
expect(slack_link).to include('&state=a+token')
|
||||
|
||||
expect(query).to include(
|
||||
'scope' => 'commands,chat:write,chat:write.public',
|
||||
'client_id' => 'A12345',
|
||||
'redirect_uri' => 'http://redirect',
|
||||
'state' => 'a token'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#gitlab_slack_application_data' do
|
||||
let_it_be(:projects) { create_list(:project, 3) }
|
||||
|
||||
def relation
|
||||
Project.id_in(projects.pluck(:id)).inc_routes
|
||||
end
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:current_user).and_return(build(:user))
|
||||
allow(helper).to receive(:new_session_path).and_return('http://session-path')
|
||||
end
|
||||
|
||||
it 'includes the required keys' do
|
||||
additions = helper.gitlab_slack_application_data(relation)
|
||||
|
||||
expect(additions.keys).to include(
|
||||
:projects,
|
||||
:sign_in_path,
|
||||
:is_signed_in,
|
||||
:slack_link_path,
|
||||
:gitlab_logo_path,
|
||||
:slack_logo_path
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not suffer from N+1 performance issues' do
|
||||
baseline = ActiveRecord::QueryRecorder.new { helper.gitlab_slack_application_data(relation.limit(1)) }
|
||||
|
||||
expect do
|
||||
helper.gitlab_slack_application_data(relation)
|
||||
end.not_to exceed_query_limit(baseline)
|
||||
end
|
||||
|
||||
it 'serializes nil projects without error' do
|
||||
expect(helper.gitlab_slack_application_data(nil)).to include(projects: '[]')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#integration_issue_type' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
let_it_be(:issue) { create(:issue) }
|
||||
|
|
|
|||
|
|
@ -8117,4 +8117,48 @@ RSpec.describe User, feature_category: :user_profile do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#arkose_global_score' do
|
||||
let_it_be(:user1) { create(:user) }
|
||||
let_it_be(:user2) { create(:user) }
|
||||
|
||||
context 'when the user has an arkose global risk score' do
|
||||
before do
|
||||
create(:abuse_trust_score, user: user1, score: 12.0, source: :arkose_global_score)
|
||||
create(:abuse_trust_score, user: user1, score: 24.0, source: :arkose_global_score)
|
||||
end
|
||||
|
||||
it 'returns the latest score' do
|
||||
expect(user1.arkose_global_score).to be(24.0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user does not have an arkose global risk score' do
|
||||
it 'defaults to zero' do
|
||||
expect(user2.arkose_global_score).to be(0.0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#arkose_custom_score' do
|
||||
let_it_be(:user1) { create(:user) }
|
||||
let_it_be(:user2) { create(:user) }
|
||||
|
||||
context 'when the user has an arkose custom risk score' do
|
||||
before do
|
||||
create(:abuse_trust_score, user: user1, score: 12.0, source: :arkose_custom_score)
|
||||
create(:abuse_trust_score, user: user1, score: 24.0, source: :arkose_custom_score)
|
||||
end
|
||||
|
||||
it 'returns the latest score' do
|
||||
expect(user1.arkose_custom_score).to be(24.0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user does not have an arkose custom risk score' do
|
||||
it 'defaults to zero' do
|
||||
expect(user2.arkose_custom_score).to be(0.0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Projects::SlackApplicationInstallService, feature_category: :integrations do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be_with_refind(:project) { create(:project) }
|
||||
|
||||
let(:integration) { project.gitlab_slack_application_integration }
|
||||
let(:installation) { integration.slack_integration }
|
||||
|
||||
let(:slack_app_id) { 'A12345' }
|
||||
let(:slack_app_secret) { 'secret' }
|
||||
let(:oauth_code) { 'code' }
|
||||
let(:params) { { code: oauth_code } }
|
||||
let(:exchange_url) { described_class::SLACK_EXCHANGE_TOKEN_URL }
|
||||
let(:redirect_url) { Gitlab::Routing.url_helpers.slack_auth_project_settings_slack_url(project) }
|
||||
|
||||
subject(:service) { described_class.new(project, user, params) }
|
||||
|
||||
before do
|
||||
stub_application_setting(slack_app_id: slack_app_id, slack_app_secret: slack_app_secret)
|
||||
|
||||
query = {
|
||||
client_id: slack_app_id,
|
||||
client_secret: slack_app_secret,
|
||||
code: oauth_code,
|
||||
redirect_uri: redirect_url
|
||||
}
|
||||
|
||||
stub_request(:get, exchange_url)
|
||||
.with(query: query)
|
||||
.to_return(body: response.to_json, headers: { 'Content-Type' => 'application/json' })
|
||||
end
|
||||
|
||||
context 'when Slack responds with an error' do
|
||||
let(:response) do
|
||||
{
|
||||
ok: false,
|
||||
error: 'something is wrong'
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns error result' do
|
||||
result = service.execute
|
||||
|
||||
expect(result).to eq(message: 'Slack: something is wrong', status: :error)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when Slack responds with an access token' do
|
||||
let_it_be(:team_id) { 'T11111' }
|
||||
let_it_be(:team_name) { 'Team name' }
|
||||
let_it_be(:user_id) { 'U11111' }
|
||||
let_it_be(:bot_user_id) { 'U99999' }
|
||||
let_it_be(:bot_access_token) { 'token-XXXXX' }
|
||||
|
||||
let(:response) do
|
||||
{
|
||||
ok: true,
|
||||
app_id: 'A12345',
|
||||
authed_user: { id: user_id },
|
||||
token_type: 'bot',
|
||||
access_token: bot_access_token,
|
||||
bot_user_id: bot_user_id,
|
||||
team: { id: team_id, name: 'Team name' },
|
||||
enterprise: { is_enterprise_install: false },
|
||||
scope: 'chat:a,chat:b,chat:c'
|
||||
}
|
||||
end
|
||||
|
||||
shared_examples 'success response' do
|
||||
it 'returns success result and creates all needed records' do
|
||||
result = service.execute
|
||||
|
||||
expect(result).to eq(status: :success)
|
||||
expect(integration).to be_present
|
||||
expect(installation).to be_present
|
||||
expect(installation).to have_attributes(
|
||||
integration_id: integration.id,
|
||||
team_id: team_id,
|
||||
team_name: team_name,
|
||||
alias: project.full_path,
|
||||
user_id: user_id,
|
||||
bot_user_id: bot_user_id,
|
||||
bot_access_token: bot_access_token,
|
||||
authorized_scope_names: contain_exactly('chat:a', 'chat:b', 'chat:c')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'success response'
|
||||
|
||||
context 'when integration record already exists' do
|
||||
before do
|
||||
project.create_gitlab_slack_application_integration!
|
||||
end
|
||||
|
||||
it_behaves_like 'success response'
|
||||
|
||||
context 'when installation record already exists' do
|
||||
before do
|
||||
integration.create_slack_integration!(
|
||||
team_id: 'old value',
|
||||
team_name: 'old value',
|
||||
alias: 'old value',
|
||||
user_id: 'old value',
|
||||
bot_user_id: 'old value',
|
||||
bot_access_token: 'old value'
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'success response'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the team has other Slack installation records' do
|
||||
let_it_be_with_reload(:other_installation) { create(:slack_integration, team_id: team_id) }
|
||||
let_it_be_with_reload(:other_legacy_installation) { create(:slack_integration, :legacy, team_id: team_id) }
|
||||
let_it_be_with_reload(:legacy_installation_for_other_team) { create(:slack_integration, :legacy) }
|
||||
|
||||
it_behaves_like 'success response'
|
||||
|
||||
it 'updates related legacy records' do
|
||||
travel_to(1.minute.from_now) do
|
||||
expected_attributes = {
|
||||
'user_id' => user_id,
|
||||
'bot_user_id' => bot_user_id,
|
||||
'bot_access_token' => bot_access_token,
|
||||
'updated_at' => Time.current,
|
||||
'authorized_scope_names' => %w[chat:a chat:b chat:c]
|
||||
}
|
||||
|
||||
service.execute
|
||||
|
||||
expect(other_installation).to have_attributes(expected_attributes)
|
||||
expect(other_legacy_installation).to have_attributes(expected_attributes)
|
||||
expect(legacy_installation_for_other_team).not_to have_attributes(expected_attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -109,7 +109,6 @@
|
|||
- './ee/spec/controllers/profiles/billings_controller_spec.rb'
|
||||
- './ee/spec/controllers/profiles_controller_spec.rb'
|
||||
- './ee/spec/controllers/profiles/keys_controller_spec.rb'
|
||||
- './ee/spec/controllers/profiles/slacks_controller_spec.rb'
|
||||
- './ee/spec/controllers/profiles/usage_quotas_controller_spec.rb'
|
||||
- './ee/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb'
|
||||
- './ee/spec/controllers/projects/analytics/issues_analytics_controller_spec.rb'
|
||||
|
|
@ -157,7 +156,6 @@
|
|||
- './ee/spec/controllers/projects/settings/integrations_controller_spec.rb'
|
||||
- './ee/spec/controllers/projects/settings/operations_controller_spec.rb'
|
||||
- './ee/spec/controllers/projects/settings/repository_controller_spec.rb'
|
||||
- './ee/spec/controllers/projects/settings/slacks_controller_spec.rb'
|
||||
- './ee/spec/controllers/projects/subscriptions_controller_spec.rb'
|
||||
- './ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb'
|
||||
- './ee/spec/controllers/registrations/company_controller_spec.rb'
|
||||
|
|
@ -2872,7 +2870,6 @@
|
|||
- './ee/spec/services/projects/protect_default_branch_service_spec.rb'
|
||||
- './ee/spec/services/projects/restore_service_spec.rb'
|
||||
- './ee/spec/services/projects/setup_ci_cd_spec.rb'
|
||||
- './ee/spec/services/projects/slack_application_install_service_spec.rb'
|
||||
- './ee/spec/services/projects/transfer_service_spec.rb'
|
||||
- './ee/spec/services/projects/update_mirror_service_spec.rb'
|
||||
- './ee/spec/services/projects/update_service_spec.rb'
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
export { withGitLabAPIAccess } from './preview';
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import { addons } from '@storybook/addons';
|
||||
import { GlBadge } from '@gitlab/ui';
|
||||
import { FORCE_REMOUNT } from '@storybook/core-events';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { GITLAB_API_ACCESS_UPDATE_EVENT } from './constants';
|
||||
|
||||
/**
|
||||
|
|
@ -66,8 +67,16 @@ export const withGitLabAPIAccess = (story, context) => {
|
|||
return {
|
||||
components: {
|
||||
story,
|
||||
GlBadge,
|
||||
},
|
||||
template: '<story />',
|
||||
template: `
|
||||
<div>
|
||||
<div class="gl-display-flex gl-justify-content-end">
|
||||
<gl-badge variant="info">Requires API access</gl-badge>
|
||||
</div>
|
||||
<story />
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import './gon';
|
||||
import Vue from 'vue';
|
||||
import translateMixin from '~/vue_shared/translate';
|
||||
import { withGitLabAPIAccess, initializeGitLabAPIAccess } from './addons/gitlab_api_access/preview';
|
||||
import { initializeGitLabAPIAccess } from './addons/gitlab_api_access/preview';
|
||||
|
||||
const stylesheetsRequireCtx = require.context(
|
||||
'../../app/assets/stylesheets',
|
||||
|
|
@ -17,5 +17,3 @@ translateMixin(Vue);
|
|||
stylesheetsRequireCtx('./application.scss');
|
||||
stylesheetsRequireCtx('./application_utilities.scss');
|
||||
stylesheetsRequireCtx('./highlight/themes/white.scss');
|
||||
|
||||
export const decorators = [withGitLabAPIAccess];
|
||||
|
|
|
|||
Loading…
Reference in New Issue