Fixed bug when external wiki is enabled
When the external wiki is enabled, the internal wiki link is replaced by the external wiki url. But the internal wiki is still accessible. In this change the external wiki will have its own tab in the sidebar and only if the services are disabled the tab (and access rights) will not be displayed.
This commit is contained in:
parent
f27cba0fee
commit
740f07b1ec
14 changed files with 131 additions and 51 deletions
|
@ -1,12 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module ExternalWikiHelper
|
|
||||||
def get_project_wiki_path(project)
|
|
||||||
external_wiki_service = project.external_wiki
|
|
||||||
if external_wiki_service
|
|
||||||
external_wiki_service.properties['external_wiki_url']
|
|
||||||
else
|
|
||||||
project_wiki_path(project, :home)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -313,19 +313,24 @@ module ProjectsHelper
|
||||||
nav_tabs << :operations
|
nav_tabs << :operations
|
||||||
end
|
end
|
||||||
|
|
||||||
if project.external_issue_tracker
|
|
||||||
nav_tabs << :external_issue_tracker
|
|
||||||
end
|
|
||||||
|
|
||||||
tab_ability_map.each do |tab, ability|
|
tab_ability_map.each do |tab, ability|
|
||||||
if can?(current_user, ability, project)
|
if can?(current_user, ability, project)
|
||||||
nav_tabs << tab
|
nav_tabs << tab
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
nav_tabs << external_nav_tabs(project)
|
||||||
|
|
||||||
nav_tabs.flatten
|
nav_tabs.flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def external_nav_tabs(project)
|
||||||
|
[].tap do |tabs|
|
||||||
|
tabs << :external_issue_tracker if project.external_issue_tracker
|
||||||
|
tabs << :external_wiki if project.has_external_wiki?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def tab_ability_map
|
def tab_ability_map
|
||||||
{
|
{
|
||||||
environments: :read_environment,
|
environments: :read_environment,
|
||||||
|
|
|
@ -314,7 +314,7 @@ class ProjectPolicy < BasePolicy
|
||||||
prevent(*create_read_update_admin_destroy(:project_snippet))
|
prevent(*create_read_update_admin_destroy(:project_snippet))
|
||||||
end
|
end
|
||||||
|
|
||||||
rule { wiki_disabled & ~has_external_wiki }.policy do
|
rule { wiki_disabled }.policy do
|
||||||
prevent(*create_read_update_admin_destroy(:wiki))
|
prevent(*create_read_update_admin_destroy(:wiki))
|
||||||
prevent(:download_wiki_code)
|
prevent(:download_wiki_code)
|
||||||
end
|
end
|
||||||
|
|
|
@ -281,19 +281,34 @@
|
||||||
%strong.fly-out-top-item-name
|
%strong.fly-out-top-item-name
|
||||||
= _('Registry')
|
= _('Registry')
|
||||||
|
|
||||||
- if project_nav_tab? :wiki
|
- if project_nav_tab?(:wiki)
|
||||||
|
- wiki_url = project_wiki_path(@project, :home)
|
||||||
= nav_link(controller: :wikis) do
|
= nav_link(controller: :wikis) do
|
||||||
= link_to get_project_wiki_path(@project), class: 'shortcuts-wiki qa-wiki-link' do
|
= link_to wiki_url, class: 'shortcuts-wiki qa-wiki-link' do
|
||||||
.nav-icon-container
|
.nav-icon-container
|
||||||
= sprite_icon('book')
|
= sprite_icon('book')
|
||||||
%span.nav-item-name
|
%span.nav-item-name
|
||||||
= _('Wiki')
|
= _('Wiki')
|
||||||
%ul.sidebar-sub-level-items.is-fly-out-only
|
%ul.sidebar-sub-level-items.is-fly-out-only
|
||||||
= nav_link(controller: :wikis, html_options: { class: "fly-out-top-item" } ) do
|
= nav_link(controller: :wikis, html_options: { class: "fly-out-top-item" } ) do
|
||||||
= link_to get_project_wiki_path(@project) do
|
= link_to wiki_url do
|
||||||
%strong.fly-out-top-item-name
|
%strong.fly-out-top-item-name
|
||||||
= _('Wiki')
|
= _('Wiki')
|
||||||
|
|
||||||
|
- if project_nav_tab?(:external_wiki)
|
||||||
|
- external_wiki_url = @project.external_wiki.external_wiki_url
|
||||||
|
= nav_link do
|
||||||
|
= link_to external_wiki_url, class: 'shortcuts-external_wiki' do
|
||||||
|
.nav-icon-container
|
||||||
|
= sprite_icon('issue-external')
|
||||||
|
%span.nav-item-name
|
||||||
|
= _('External Wiki')
|
||||||
|
%ul.sidebar-sub-level-items.is-fly-out-only
|
||||||
|
= nav_link(html_options: { class: "fly-out-top-item" } ) do
|
||||||
|
= link_to external_wiki_url do
|
||||||
|
%strong.fly-out-top-item-name
|
||||||
|
= _('External Wiki')
|
||||||
|
|
||||||
- if project_nav_tab? :snippets
|
- if project_nav_tab? :snippets
|
||||||
= nav_link(controller: :snippets) do
|
= nav_link(controller: :snippets) do
|
||||||
= link_to project_snippets_path(@project), class: 'shortcuts-snippets' do
|
= link_to project_snippets_path(@project), class: 'shortcuts-snippets' do
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= icon('info-circle fw')
|
= icon('info-circle fw')
|
||||||
= succeed '.' do
|
= succeed '.' do
|
||||||
To learn more about this project, read
|
To learn more about this project, read
|
||||||
= link_to "the wiki", get_project_wiki_path(viewer.project)
|
= link_to "the wiki", project_wiki_path(viewer.project, :home)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- @no_container = true
|
- @no_container = true
|
||||||
- add_to_breadcrumbs "Wiki", get_project_wiki_path(@project)
|
- add_to_breadcrumbs "Wiki", project_wiki_path(@project, :home)
|
||||||
- breadcrumb_title s_("Wiki|Pages")
|
- breadcrumb_title s_("Wiki|Pages")
|
||||||
- page_title s_("Wiki|Pages"), _("Wiki")
|
- page_title s_("Wiki|Pages"), _("Wiki")
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
- breadcrumb_title @page.human_title
|
- breadcrumb_title @page.human_title
|
||||||
- wiki_breadcrumb_dropdown_links(@page.slug)
|
- wiki_breadcrumb_dropdown_links(@page.slug)
|
||||||
- page_title @page.human_title, _("Wiki")
|
- page_title @page.human_title, _("Wiki")
|
||||||
- add_to_breadcrumbs _("Wiki"), get_project_wiki_path(@project)
|
- add_to_breadcrumbs _("Wiki"), project_wiki_path(@project, :home)
|
||||||
|
|
||||||
.wiki-page-header.has-sidebar-toggle
|
.wiki-page-header.has-sidebar-toggle
|
||||||
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
|
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Fix wiki access rights when external wiki is enabled
|
||||||
|
merge_request:
|
||||||
|
author:
|
||||||
|
type: security
|
|
@ -3151,6 +3151,9 @@ msgstr ""
|
||||||
msgid "External URL"
|
msgid "External URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External Wiki"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Facebook"
|
msgid "Facebook"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -358,6 +358,26 @@ describe ProjectsHelper do
|
||||||
is_expected.not_to include(:pipelines)
|
is_expected.not_to include(:pipelines)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when project has external wiki' do
|
||||||
|
before do
|
||||||
|
allow(project).to receive(:has_external_wiki?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes external wiki tab' do
|
||||||
|
is_expected.to include(:external_wiki)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when project does not have external wiki' do
|
||||||
|
before do
|
||||||
|
allow(project).to receive(:has_external_wiki?).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not include external wiki tab' do
|
||||||
|
is_expected.not_to include(:external_wiki)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#show_projects' do
|
describe '#show_projects' do
|
||||||
|
|
|
@ -298,7 +298,6 @@ describe Ability do
|
||||||
|
|
||||||
context 'wiki named abilities' do
|
context 'wiki named abilities' do
|
||||||
it 'disables wiki abilities if the project has no wiki' do
|
it 'disables wiki abilities if the project has no wiki' do
|
||||||
expect(project).to receive(:has_external_wiki?).and_return(false)
|
|
||||||
expect(subject).not_to be_allowed(:read_wiki)
|
expect(subject).not_to be_allowed(:read_wiki)
|
||||||
expect(subject).not_to be_allowed(:create_wiki)
|
expect(subject).not_to be_allowed(:create_wiki)
|
||||||
expect(subject).not_to be_allowed(:update_wiki)
|
expect(subject).not_to be_allowed(:update_wiki)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe ExternalWikiService do
|
describe ExternalWikiService do
|
||||||
include ExternalWikiHelper
|
|
||||||
describe "Associations" do
|
describe "Associations" do
|
||||||
it { is_expected.to belong_to :project }
|
it { is_expected.to belong_to :project }
|
||||||
it { is_expected.to have_one :service_hook }
|
it { is_expected.to have_one :service_hook }
|
||||||
|
@ -25,24 +24,4 @@ describe ExternalWikiService do
|
||||||
it { is_expected.not_to validate_presence_of(:external_wiki_url) }
|
it { is_expected.not_to validate_presence_of(:external_wiki_url) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'External wiki' do
|
|
||||||
let(:project) { create(:project) }
|
|
||||||
|
|
||||||
context 'when it is active' do
|
|
||||||
before do
|
|
||||||
properties = { 'external_wiki_url' => 'https://gitlab.com' }
|
|
||||||
@service = project.create_external_wiki_service(active: true, properties: properties)
|
|
||||||
end
|
|
||||||
|
|
||||||
after do
|
|
||||||
@service.destroy!
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'replaces the wiki url' do
|
|
||||||
wiki_path = get_project_wiki_path(project)
|
|
||||||
expect(wiki_path).to match('https://gitlab.com')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -102,15 +102,27 @@ describe ProjectPolicy do
|
||||||
expect(Ability).not_to be_allowed(user, :read_issue, project)
|
expect(Ability).not_to be_allowed(user, :read_issue, project)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the feature is disabled' do
|
context 'wiki feature' do
|
||||||
|
let(:permissions) { %i(read_wiki create_wiki update_wiki admin_wiki download_wiki_code) }
|
||||||
|
|
||||||
subject { described_class.new(owner, project) }
|
subject { described_class.new(owner, project) }
|
||||||
|
|
||||||
|
context 'when the feature is disabled' do
|
||||||
before do
|
before do
|
||||||
project.project_feature.update_attribute(:wiki_access_level, ProjectFeature::DISABLED)
|
project.project_feature.update_attribute(:wiki_access_level, ProjectFeature::DISABLED)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not include the wiki permissions' do
|
it 'does not include the wiki permissions' do
|
||||||
expect_disallowed :read_wiki, :create_wiki, :update_wiki, :admin_wiki, :download_wiki_code
|
expect_disallowed(*permissions)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there is an external wiki' do
|
||||||
|
it 'does not include the wiki permissions' do
|
||||||
|
allow(project).to receive(:has_external_wiki?).and_return(true)
|
||||||
|
|
||||||
|
expect_disallowed(*permissions)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -57,4 +57,58 @@ describe 'layouts/nav/sidebar/_project' do
|
||||||
expect(rendered).to have_link('Releases', href: project_releases_path(project))
|
expect(rendered).to have_link('Releases', href: project_releases_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'wiki entry tab' do
|
||||||
|
let(:can_read_wiki) { true }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(view).to receive(:can?).with(nil, :read_wiki, project).and_return(can_read_wiki)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when wiki is enabled' do
|
||||||
|
it 'shows the wiki tab with the wiki internal link' do
|
||||||
|
render
|
||||||
|
|
||||||
|
expect(rendered).to have_link('Wiki', href: project_wiki_path(project, :home))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when wiki is disabled' do
|
||||||
|
let(:can_read_wiki) { false }
|
||||||
|
|
||||||
|
it 'does not show the wiki tab' do
|
||||||
|
render
|
||||||
|
|
||||||
|
expect(rendered).not_to have_link('Wiki', href: project_wiki_path(project, :home))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'external wiki entry tab' do
|
||||||
|
let(:properties) { { 'external_wiki_url' => 'https://gitlab.com' } }
|
||||||
|
let(:service_status) { true }
|
||||||
|
|
||||||
|
before do
|
||||||
|
project.create_external_wiki_service(active: service_status, properties: properties)
|
||||||
|
project.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is active' do
|
||||||
|
it 'shows the external wiki tab with the external wiki service link' do
|
||||||
|
render
|
||||||
|
|
||||||
|
expect(rendered).to have_link('External Wiki', href: properties['external_wiki_url'])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is disabled' do
|
||||||
|
let(:service_status) { false }
|
||||||
|
|
||||||
|
it 'does not show the external wiki tab' do
|
||||||
|
render
|
||||||
|
|
||||||
|
expect(rendered).not_to have_link('External Wiki', href: project_wiki_path(project, :home))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue