Commit ddef87b7 authored by Nick Thomas's avatar Nick Thomas

Namespace license checks for exporting issues (EES)

parent 3863e46b
module EE
module Projects
module IssuesController
extend ActiveSupport::Concern
included do
before_action :check_export_issues_available!, only: [:export_csv]
end
def export_csv
ExportCsvWorker.perform_async(current_user.id, project.id, filter_params)
index_path = namespace_project_issues_path(project.namespace, project)
redirect_to(index_path, notice: "Your CSV export has started. It will be emailed to #{current_user.notification_email} when complete.")
end
end
end
end
......@@ -53,9 +53,16 @@ class Projects::ApplicationController < ApplicationController
end
end
def check_project_feature_available!(feature)
render_404 unless project.feature_available?(feature, current_user)
end
def method_missing(method_sym, *arguments, &block)
if method_sym.to_s =~ /\Aauthorize_(.*)!\z/
case method_sym.to_s
when /\Aauthorize_(.*)!\z/
authorize_action!($1.to_sym)
when /\Acheck_(.*)_available!\z/
check_project_feature_available!($1.to_sym)
else
super
end
......
......@@ -6,6 +6,8 @@ class Projects::IssuesController < Projects::ApplicationController
include IssuableCollections
include SpammableActions
include ::EE::Projects::IssuesController
prepend_before_action :authenticate_user!, only: [:new, :export_csv]
before_action :redirect_to_external_issue_tracker, only: [:index, :new]
......@@ -156,13 +158,6 @@ class Projects::IssuesController < Projects::ApplicationController
render_conflict_response
end
def export_csv
ExportCsvWorker.perform_async(@current_user.id, @project.id, filter_params)
index_path = namespace_project_issues_path(@project.namespace, @project)
redirect_to(index_path, notice: "Your CSV export has started. It will be emailed to #{current_user.notification_email} when complete.")
end
def referenced_merge_requests
@merge_requests = @issue.referenced_merge_requests(current_user)
@closed_by_merge_requests = @issue.closed_by_merge_requests(current_user)
......
......@@ -9,6 +9,7 @@ class License < ActiveRecord::Base
OBJECT_STORAGE_FEATURE = 'GitLab_ObjectStorage'.freeze
ELASTIC_SEARCH_FEATURE = 'GitLab_ElasticSearch'.freeze
RELATED_ISSUES_FEATURE = 'RelatedIssues'.freeze
EXPORT_ISSUES_FEATURE = 'GitLab_ExportIssues'.freeze
FEATURE_CODES = {
geo: GEO_FEATURE,
......@@ -19,7 +20,8 @@ class License < ActiveRecord::Base
related_issues: RELATED_ISSUES_FEATURE,
# Features that make sense to Namespace:
deploy_board: DEPLOY_BOARD_FEATURE,
file_lock: FILE_LOCK_FEATURE
file_lock: FILE_LOCK_FEATURE,
export_issues: EXPORT_ISSUES_FEATURE
}.freeze
STARTER_PLAN = 'starter'.freeze
......@@ -29,7 +31,8 @@ class License < ActiveRecord::Base
EES_FEATURES = [
{ ELASTIC_SEARCH_FEATURE => 1 },
{ RELATED_ISSUES_FEATURE => 1 }
{ RELATED_ISSUES_FEATURE => 1 },
{ EXPORT_ISSUES_FEATURE => 1 }
].freeze
EEP_FEATURES = [
......@@ -61,7 +64,8 @@ class License < ActiveRecord::Base
{ GEO_FEATURE => 1 },
{ AUDITOR_USER_FEATURE => 1 },
{ SERVICE_DESK_FEATURE => 1 },
{ OBJECT_STORAGE_FEATURE => 1 }
{ OBJECT_STORAGE_FEATURE => 1 },
{ EXPORT_ISSUES_FEATURE => 1 }
].freeze
FEATURES_BY_PLAN = {
......
- if current_user && @project.feature_available?(:export_issues)
%button.csv_download_link.btn.append-right-10.has-tooltip{ title: 'Export as CSV' }
= icon('download')
- return unless current_user && @project.feature_available?(:export_issues)
.issues-export-modal.modal
.modal-dialog
.modal-content
......
......@@ -15,17 +15,18 @@
= auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@project.name} issues")
- if project_issues(@project).exists?
- if current_user
= render "projects/issues/export_issues/csv_download"
= render 'projects/issues/export_issues/csv_download'
%div{ class: (container_class) }
.top-area
= render 'shared/issuable/nav', type: :issues
.nav-controls.inline
= link_to params.merge(rss_url_options), class: 'btn append-right-10 has-tooltip', title: 'Subscribe' do
= icon('rss')
- if current_user
%button.csv_download_link.btn.append-right-10.has-tooltip{ title: 'Export as CSV' }
= icon('download')
= render 'projects/issues/export_issues/button'
- if @can_bulk_update
= button_tag "Edit Issues", class: "btn btn-default js-bulk-update-toggle"
= link_to new_namespace_project_issue_path(@project.namespace,
......
---
title: Namespace license checks for exporting issues (EES)
merge_request: 2164
author:
require('spec_helper')
describe Projects::IssuesController do
let(:namespace) { create(:namespace) }
let(:project) { create(:project_empty_repo, namespace: namespace) }
let(:user) { create(:user) }
let(:viewer) { user }
let(:issue) { create(:issue, project: project) }
describe 'POST export_csv' do
let(:globally_licensed) { false }
before do
project.add_developer(user)
sign_in(viewer) if viewer
allow(License).to receive(:feature_available?).and_call_original
allow(License).to receive(:feature_available?).with(:export_issues).and_return(globally_licensed)
end
def request_csv
post :export_csv, namespace_id: project.namespace.to_param, project_id: project.to_param
end
context 'unlicensed' do
it 'returns 404' do
expect(ExportCsvWorker).not_to receive(:perform_async)
request_csv
expect(response.status).to eq(404)
end
end
context 'globally licensed' do
let(:globally_licensed) { true }
it 'allows CSV export' do
expect(ExportCsvWorker).to receive(:perform_async).with(viewer.id, project.id, anything)
request_csv
expect(response).to redirect_to(namespace_project_issues_path(project.namespace, project))
expect(response.flash[:notice]).to match(/\AYour CSV export has started/i)
end
context 'anonymous user' do
let(:project) { create(:project_empty_repo, :public, namespace: namespace) }
let(:viewer) { nil }
it 'redirects to the sign in page' do
request_csv
expect(ExportCsvWorker).not_to receive(:perform_async)
expect(response).to redirect_to(new_user_session_path)
end
end
end
context 'licensed by namespace' do
let(:globally_licensed) { true }
let(:namespace) { create(:group, :private, plan: Namespace::BRONZE_PLAN) }
before do
stub_application_setting(check_namespace_plan: true)
end
it 'allows CSV export' do
expect(ExportCsvWorker).to receive(:perform_async).with(viewer.id, project.id, anything)
request_csv
expect(response).to redirect_to(namespace_project_issues_path(project.namespace, project))
expect(response.flash[:notice]).to match(/\AYour CSV export has started/i)
end
end
end
end
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