Skip to content

Commit

Permalink
Merge branch 'dev' into task/50684-migrate-to-httpx-http-ruby-client
Browse files Browse the repository at this point in the history
  • Loading branch information
ba1ash committed Dec 18, 2023
2 parents 21fa5aa + 0be29ca commit 12b1dda
Show file tree
Hide file tree
Showing 16 changed files with 243 additions and 31 deletions.
3 changes: 2 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,11 @@ group :test do
gem 'rails-controller-testing', '~> 1.0.2'

gem 'capybara', '~> 3.39.0'
gem 'capybara_accessible_selectors', git: 'https://github.com/citizensadvice/capybara_accessible_selectors', branch: 'main'
gem 'capybara-screenshot', '~> 1.0.17'
gem 'cuprite', '~> 0.15.0'
gem 'selenium-devtools'
gem 'selenium-webdriver', '~> 4.16.0'
gem 'capybara_accessible_selectors', git: 'https://github.com/citizensadvice/capybara_accessible_selectors', branch: 'main'

gem 'fuubar', '~> 2.5.0'
gem 'timecop', '~> 0.9.0'
Expand Down
13 changes: 8 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ GEM
paper_trail (12.3.0)
activerecord (>= 5.2)
request_store (~> 1.1)
parallel (1.23.0)
parallel (1.24.0)
parallel_tests (4.3.0)
parallel
parser (3.2.2.4)
Expand Down Expand Up @@ -849,7 +849,7 @@ GEM
rb-inotify (0.10.1)
ffi (~> 1.0)
rbtree3 (0.7.1)
rdoc (6.6.1)
rdoc (6.6.2)
psych (>= 4.0.0)
recaptcha (5.16.0)
redcarpet (3.6.0)
Expand Down Expand Up @@ -920,9 +920,9 @@ GEM
activesupport
rubocop
rubocop-rspec
rubocop-performance (1.19.1)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
rubocop-performance (1.20.0)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rails (2.22.2)
activesupport (>= 4.2.0)
rack (>= 1.1)
Expand Down Expand Up @@ -951,6 +951,8 @@ GEM
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
secure_headers (6.5.0)
selenium-devtools (0.120.0)
selenium-webdriver (~> 4.2)
selenium-webdriver (4.16.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
Expand Down Expand Up @@ -1225,6 +1227,7 @@ DEPENDENCIES
rubytree (~> 2.0.0)
sanitize (~> 6.1.0)
secure_headers (~> 6.5.0)
selenium-devtools
selenium-webdriver (~> 4.16.0)
semantic (~> 1.6.1)
shoulda-context (~> 2.0)
Expand Down
14 changes: 2 additions & 12 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,13 @@ class Project < ApplicationRecord
friendly_id :identifier, use: :finders

include ::Scopes::Scoped
scopes :allowed_to
scopes :allowed_to,
:visible

scope :has_module, ->(mod) {
where(["#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s])
}
scope :public_projects, -> { where(public: true) }
scope :visible, ->(user = User.current) { where(id: Project.visible_by(user)) }
scope :with_visible_work_packages, ->(user = User.current) do
where(id: WorkPackage.visible(user).select(:project_id)).or(allowed_to(user, :view_work_packages))
end
Expand Down Expand Up @@ -199,16 +199,6 @@ def self.selectable_projects
Project.visible.select { |p| User.current.member_of? p }.sort_by(&:to_s)
end

# Returns all projects the user is allowed to see.
#
# Employs the :view_project permission to perform the
# authorization check as the permission is public, meaning it is granted
# to everybody having at least one role in a project regardless of the
# role's permissions.
def self.visible_by(user = User.current)
allowed_to(user, :view_project).or(where(id: WorkPackage.visible(user).select(:project_id)))
end

# Returns a :conditions SQL string that can be used to find the issues associated with this project.
#
# Examples:
Expand Down
50 changes: 50 additions & 0 deletions app/models/projects/scopes/visible.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# -- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2010-2023 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
# ++

module Projects::Scopes
module Visible
extend ActiveSupport::Concern

class_methods do
# Returns all projects the user is allowed to see.
# Those include projects where the user has the permission:
# * :view_project via a project role (which might also be the non member/anonymous role) or by being administrator
# * :view_work_packages via a work package role
def visible(user = User.current)
# Use a shortcut for admins and anonymous where
# we don't need to calculate for work package roles which is more expensive
if user.admin? || user.anonymous?
Project.allowed_to(user, :view_project)
else
Project.allowed_to(user, :view_project)
.or(where(id: WorkPackage.allowed_to(user, :view_work_packages).select(:project_id)))
end
end
end
end
end
4 changes: 2 additions & 2 deletions docker/ci/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ setup_tests() {
run_background backend_stuff
run_background frontend_stuff
# pre-cache browsers and their drivers binaries
run_background $(bundle show selenium)/bin/linux/selenium-manager --browser chrome --debug
run_background $(bundle show selenium)/bin/linux/selenium-manager --browser firefox --debug
run_background $(bundle show selenium-webdriver)/bin/linux/selenium-manager --browser chrome --debug
run_background $(bundle show selenium-webdriver)/bin/linux/selenium-manager --browser firefox --debug
wait_for_background
}

Expand Down
6 changes: 6 additions & 0 deletions frontend/src/app/core/setup/globals/global-listeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ export function initializeGlobalListeners():void {
return;
}

// Avoid opening new tab when clicking links while editing in ckeditor
if (linkElement.classList.contains('ck-link_selected')) {
evt.preventDefault();
return;
}

const callbacks = [
openExternalLinksInNewTab,
performAnchorHijacking,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def search(tokens, projects = nil, options = {})

def searchable_projects_condition
projects = if searchable_options[:permission].nil?
Project.visible_by(User.current)
Project.visible(User.current)
else
Project.allowed_to(User.current, searchable_options[:permission])
end
Expand Down
10 changes: 10 additions & 0 deletions modules/bim/spec/features/bcf/api_authorization_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,18 @@ def oauth_path(client_id)

logout

# A basic auth alert is displayed asking to enter name and password Register
# some basic auth credentials
# - A non-matching url is used so that capybara will issue a CancelAuth
# instead of trying to authenticate
# - The register method is not recognized by selenium-webdriver with Chrome
# 120 with old headless
if page.driver.browser.respond_to?(:register)
page.driver.browser.register(username: 'foo', password: 'bar', uri: /does_not_match/)
end
# While not being logged in and without a token, the api cannot be accessed
visit("/api/bcf/2.1/projects/#{project.id}")
# Cancel button of basic auth should have been chosen now
expect(page)
.to have_content(JSON.dump({ message: "You need to be authenticated to access this resource." }))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<%=
content_tag("turbo-frame", id: "edit-participants-dialog-frame") do
component_wrapper do
component_wrapper(class: 'Overlay-form') do
primer_form_with(
model: @meeting,
method: :put,
url: update_participants_meeting_path(@meeting)
url: update_participants_meeting_path(@meeting),
class: 'Overlay-form'
) do |f|
component_collection do |collection|
collection.with_component(Primer::Alpha::Dialog::Body.new(style: "max-height: 460px;", my: 3)) do
collection.with_component(Primer::Alpha::Dialog::Body.new(my: 3)) do
flex_layout(mt: 3) do |form_container|
form_container.with_row do
flex_layout(justify_content: :flex_end) do |header|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
id: "#{@id}-frame",
loading: :lazy,
src: @src,
class: 'Overlay-form',
data: { 'op-turbo-op-primer-async-dialog-target': "frameElement" }) do
flex_layout(justify_content: :center) do |flex|
flex.with_column(my: 5) do
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<%=
content_tag("turbo-frame", id: "add-work-package-to-meeting-dialog-frame") do
component_wrapper do
component_wrapper(class: 'Overlay-form') do
primer_form_with(
model: @meeting_agenda_item,
method: :post,
url: work_package_meeting_agenda_items_path(@work_package)
url: work_package_meeting_agenda_items_path(@work_package),
class: 'Overlay-form'
) do |f|
component_collection do |collection|
collection.with_component(Primer::Alpha::Dialog::Body.new(test_selector: 'op-add-work-package-to-meeting-dialog-body')) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
require_relative '../../support/pages/my/page'

RSpec.describe 'My spent time widget with a negative time zone', :js,
driver: :chrome_headless_new,
with_settings: { start_of_week: 1 } do
let(:beginning_of_week) { monday }
let(:end_of_week) { sunday }
Expand Down
130 changes: 130 additions & 0 deletions spec/models/projects/scopes/visible_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# -- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2010-2023 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
# ++

require 'spec_helper'

RSpec.describe Projects::Scopes::Visible do
shared_let(:activity) { create(:time_entry_activity) }
shared_let(:project) { create(:project) }
shared_let(:public_project) { create(:public_project) }
shared_let(:work_package) { create(:work_package, project:) }
shared_let(:shared_in_project) { create(:project) }
shared_let(:shared_work_package) { create(:work_package, project: shared_in_project) }
shared_let(:view_work_package_role) { create(:view_work_package_role) }
shared_let(:non_member_role) { create(:non_member) }
shared_let(:anonymous_role) { create(:anonymous_role) }
shared_let(:shared_user) do
create(:user).tap do |u|
create(:member,
project:,
principal: u,
roles: [create(:project_role)])

create(:work_package_member,
entity: shared_work_package,
principal: u,
roles: [view_work_package_role])
end
end
shared_let(:admin_user) { create(:admin) }
shared_let(:only_project_user) do
create(:user).tap do |u|
create(:member,
project:,
principal: u,
roles: [create(:project_role)])
end
end
shared_let(:only_shared_user) do
create(:user).tap do |u|
create(:work_package_member,
entity: shared_work_package,
principal: u,
roles: [view_work_package_role])
end
end
shared_let(:no_membership_user) do
create(:user)
end

subject { Project.visible(current_user) }

context 'for an admin user' do
let(:current_user) { admin_user }

it 'list all projects' do
expect(subject)
.to contain_exactly(shared_in_project, project, public_project)
end
end

context 'for a user a work package is shared with and who has a memberships' do
let(:current_user) { shared_user }

it 'list all projects' do
expect(subject)
.to contain_exactly(shared_in_project, project, public_project)
end
end

context 'for a user having only a project membership' do
let(:current_user) { only_project_user }

it 'list only the project in which the user has the membership and the public project' do
expect(subject)
.to contain_exactly(project, public_project)
end
end

context 'for a user only having a share' do
let(:current_user) { only_shared_user }

it 'list only the project in which the shared work package is and the public project' do
expect(subject)
.to contain_exactly(shared_in_project, public_project)
end
end

context 'for a user without any permission' do
let(:current_user) { no_membership_user }

it 'list only the public project' do
expect(subject)
.to contain_exactly(public_project)
end
end

context 'for an anonymous user' do
let(:current_user) { create(:anonymous) }

it 'list only the public project' do
expect(subject)
.to contain_exactly(public_project)
end
end
end
Loading

0 comments on commit 12b1dda

Please sign in to comment.