mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Placeholder user services and administration (#8944)
* Adding placeholder user contracts * Adding create, update, and delete services for placeholder users * WIP: Adding Placeholder User contract specs [ci skip] * Extract contract validation into common helper * Add common validation in BaseContract + common example for admin checks * Introduce common ModelContract shared context for validations * WIP: PlaceholderUser controller, i18n, and routes [ci skip] * Placeholder users index page and query - moved all group related scopes from User to Principal to make them also available in PlaceholderUser. * end * Create PlaceholderUser * Feature spec for editing a placeholder user * Manage PlaceholderUser memberships The managment of memberships is pretty similar for User and PlaceholderUser. This commit extacts the similarities and uses them for both. * General partial and show view for PlaceholderUser * Delete obosolete partial * Allow RequireAdminGuard to be used as a module function * Fix I18n for confirmation text * Smaller code improvements * Fix: Syntax for accessing status enums was wrong. * Use UpdateService for updating a placeholder user * Add spec for PlaceholderUsersController * First code improvements after code review. - more improvements to come. * Further code improvements after review ... still more to come * Correct namespace of delete service * Fix: Make placeholder user contract validate * Remove :type attribute from base contract of User and PlaceholerUser ...and add it to the CreateContracts. Also add type validations. Further extract shared examples for placeholder user attribute validation * Refactor: Extract membership hook calls to helper * Fix redirect paths for membership controllers * Specs already present in shared exampels. * Fix duplicates routes for users and placeholder users * Fix user path * Add attribute name and lastname We don't need a writeable check as both are equally writable * Replace more references to tab_edit_user_path * Skip specs for PlaceholderUsers::DeletionService We will tackle that service in a separate PR. * Fix module usage of RequireAdminGuard * Fix group filter for placeholder users * Fix invalid reference to expect_valid * Fix: Fix tabbed edit path for placeholder users * Fix status filtering on users * Linting * Improve generalisation of individual principal filter cell - Check for presence of groups and statuses in order to toggle visibility of their UI element. - Remove groups from placeholder user controller and cell initialization and options * Fix selector on groups assign * Remove using_shared_fixtures Co-authored-by: Oliver Günther <mail@oliverguenther.de>
This commit is contained in:
committed by
GitHub
parent
6895974095
commit
a18954b2c9
@@ -0,0 +1,117 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class IndividualPrincipalBaseFilterCell < RailsCell
|
||||
include UsersHelper
|
||||
include ActionView::Helpers::FormOptionsHelper
|
||||
|
||||
class << self
|
||||
def query(params)
|
||||
q = base_query.new
|
||||
|
||||
apply_filters(params, q)
|
||||
|
||||
q
|
||||
end
|
||||
|
||||
def filter(params)
|
||||
query(params).results
|
||||
end
|
||||
|
||||
def filtered?(params)
|
||||
%i(name status group_id role_id).any? { |name| params[name].present? }
|
||||
end
|
||||
|
||||
def filter_name(query, name)
|
||||
if name.present?
|
||||
query.where(:any_name_attribute, '~', name)
|
||||
end
|
||||
end
|
||||
|
||||
def filter_group(query, group_id)
|
||||
if group_id.present?
|
||||
query.where(:group, '=', group_id)
|
||||
end
|
||||
end
|
||||
|
||||
def filter_role(query, role_id)
|
||||
if role_id.present?
|
||||
query.where(:role_id, '=', role_id)
|
||||
end
|
||||
end
|
||||
|
||||
def filter_project(query, project_id)
|
||||
if project_id.present?
|
||||
query.where(:project_id, '=', project_id)
|
||||
end
|
||||
end
|
||||
|
||||
def base_query
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def apply_filters(params, query)
|
||||
filter_project query, params[:project_id]
|
||||
filter_name query, params[:name]
|
||||
filter_group query, params[:group_id]
|
||||
filter_role query, params[:role_id]
|
||||
|
||||
query
|
||||
end
|
||||
end
|
||||
|
||||
# INSTANCE METHODS:
|
||||
|
||||
def filter_path
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def initially_visible?
|
||||
true
|
||||
end
|
||||
|
||||
def has_close_icon?
|
||||
false
|
||||
end
|
||||
|
||||
def has_statuses?
|
||||
defined?(status)
|
||||
end
|
||||
|
||||
def has_groups?
|
||||
defined?(groups) && groups.present?
|
||||
end
|
||||
|
||||
def params
|
||||
model
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module PlaceholderUsers
|
||||
class PlaceholderUserFilterCell < IndividualPrincipalBaseFilterCell
|
||||
options :roles, :clear_url, :project
|
||||
|
||||
class << self
|
||||
def base_query
|
||||
Queries::PlaceholderUsers::PlaceholderUserQuery
|
||||
end
|
||||
end
|
||||
|
||||
# INSTANCE METHODS:
|
||||
|
||||
def filter_path
|
||||
placeholder_users_path
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module PlaceholderUsers
|
||||
class RowCell < ::RowCell
|
||||
include AvatarHelper
|
||||
include UsersHelper
|
||||
|
||||
def placeholder_user
|
||||
model
|
||||
end
|
||||
|
||||
def name
|
||||
link_to h(placeholder_user.name), edit_placeholder_user_path(placeholder_user)
|
||||
end
|
||||
|
||||
def button_links
|
||||
[delete_link].compact
|
||||
end
|
||||
|
||||
def delete_link
|
||||
return nil unless User.current.admin?
|
||||
|
||||
link_to '',
|
||||
placeholder_user_path(placeholder_user),
|
||||
data: { confirm: I18n.t(:text_are_you_sure) },
|
||||
class: 'icon icon-delete',
|
||||
method: :delete
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module PlaceholderUsers
|
||||
class TableCell < ::TableCell
|
||||
options :current_user # adds this option to those of the base class
|
||||
columns :name, :created_at
|
||||
|
||||
def initial_sort
|
||||
%i[id asc]
|
||||
end
|
||||
|
||||
def headers
|
||||
columns.map do |name|
|
||||
[name.to_s, header_options(name)]
|
||||
end
|
||||
end
|
||||
|
||||
def header_options(name)
|
||||
options = { caption: PlaceholderUser.human_attribute_name(name) }
|
||||
|
||||
options[:default_order] = 'desc' if desc_by_default.include? name
|
||||
|
||||
options
|
||||
end
|
||||
|
||||
def desc_by_default
|
||||
[:created_at]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,30 +1,37 @@
|
||||
class UserFilterCell < RailsCell
|
||||
include UsersHelper
|
||||
include ActionView::Helpers::FormOptionsHelper
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class UserFilterCell < IndividualPrincipalBaseFilterCell
|
||||
options :groups, :status, :roles, :clear_url, :project
|
||||
|
||||
class << self
|
||||
def query(params)
|
||||
q = base_query.new
|
||||
|
||||
filter_project q, params[:project_id]
|
||||
filter_name q, params[:name]
|
||||
filter_status q, status_param(params)
|
||||
filter_group q, params[:group_id]
|
||||
filter_role q, params[:role_id]
|
||||
|
||||
q
|
||||
end
|
||||
|
||||
def filter(params)
|
||||
query(params).results
|
||||
end
|
||||
|
||||
def filtered?(params)
|
||||
%i(name status group_id role_id).any? { |name| params[name].present? }
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the selected status from the parameters
|
||||
# or the default status to be filtered by (all)
|
||||
@@ -33,12 +40,6 @@ class UserFilterCell < RailsCell
|
||||
params[:status].presence || 'all'
|
||||
end
|
||||
|
||||
def filter_name(query, name)
|
||||
if name.present?
|
||||
query.where(:any_name_attribute, '~', name)
|
||||
end
|
||||
end
|
||||
|
||||
def filter_status(query, status)
|
||||
return unless status && status != 'all'
|
||||
|
||||
@@ -53,27 +54,19 @@ class UserFilterCell < RailsCell
|
||||
end
|
||||
end
|
||||
|
||||
def filter_group(query, group_id)
|
||||
if group_id.present?
|
||||
query.where(:group, '=', group_id)
|
||||
end
|
||||
end
|
||||
|
||||
def filter_role(query, role_id)
|
||||
if role_id.present?
|
||||
query.where(:role_id, '=', role_id)
|
||||
end
|
||||
end
|
||||
|
||||
def filter_project(query, project_id)
|
||||
if project_id.present?
|
||||
query.where(:project_id, '=', project_id)
|
||||
end
|
||||
end
|
||||
|
||||
def base_query
|
||||
Queries::Users::UserQuery
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
def apply_filters(params, query)
|
||||
super(params, query)
|
||||
filter_status query, status_param(params)
|
||||
|
||||
query
|
||||
end
|
||||
end
|
||||
|
||||
# INSTANCE METHODS:
|
||||
@@ -82,18 +75,6 @@ class UserFilterCell < RailsCell
|
||||
users_path
|
||||
end
|
||||
|
||||
def initially_visible?
|
||||
true
|
||||
end
|
||||
|
||||
def has_close_icon?
|
||||
false
|
||||
end
|
||||
|
||||
def params
|
||||
model
|
||||
end
|
||||
|
||||
def user_status_options
|
||||
users_status_options_for_select status, extra: extra_user_status_options
|
||||
end
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module Users
|
||||
class UserFilterCell < ::UserFilterCell
|
||||
def filter_role(query, role_id)
|
||||
|
||||
+5
-3
@@ -37,11 +37,13 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
</a>
|
||||
<% end %>
|
||||
<ul class="simple-filters--filters">
|
||||
<li class="simple-filters--filter">
|
||||
<% if has_statuses? %>
|
||||
<li class="simple-filters--filter">
|
||||
<label class='simple-filters--filter-name' for='status'><%= User.human_attribute_name(:status) %>:</label>
|
||||
<%= select_tag 'status', user_status_options, class: 'simple-filters--filter-value' %>
|
||||
</li>
|
||||
<% if groups.present? %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if has_groups? %>
|
||||
<li class="simple-filters--filter">
|
||||
<label class='simple-filters--filter-name' for='group_id'><%= Group.model_name.human %>:</label>
|
||||
<%= collection_select :group,
|
||||
@@ -30,10 +30,9 @@
|
||||
|
||||
module AttributeHelpTexts
|
||||
class BaseContract < ::ModelContract
|
||||
include RequiresAdminGuard
|
||||
include Attachments::ValidateReplacements
|
||||
|
||||
validate :validate_user_allowed_to_manage
|
||||
|
||||
def self.model
|
||||
AttributeHelpText
|
||||
end
|
||||
@@ -41,9 +40,5 @@ module AttributeHelpTexts
|
||||
attribute :type
|
||||
attribute :attribute_name
|
||||
attribute :help_text
|
||||
|
||||
def validate_user_allowed_to_manage
|
||||
errors.add :base, :error_unauthorized unless user.admin?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,12 +32,14 @@ module RequiresAdminGuard
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
validate :validate_admin_only
|
||||
validate { validate_admin_only(user, errors) }
|
||||
end
|
||||
|
||||
def validate_admin_only
|
||||
unless user.admin?
|
||||
errors.add :base, :error_unauthorized
|
||||
end
|
||||
module_function
|
||||
|
||||
def validate_admin_only(user, errors)
|
||||
unless user.admin? && user.active?
|
||||
errors.add :base, :error_unauthorized
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,7 +56,7 @@ class DeleteContract < ModelContract
|
||||
|
||||
case permission
|
||||
when :admin
|
||||
user.admin?
|
||||
user.admin? && user.active?
|
||||
when Proc
|
||||
instance_exec(&permission)
|
||||
else
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module PlaceholderUsers
|
||||
class BaseContract < ::ModelContract
|
||||
# attribute_alias is broken in the sense
|
||||
# that `model#changed` includes only the non-aliased name
|
||||
# hence we need to put "lastname" as an attribute here
|
||||
attribute :name
|
||||
attribute :lastname
|
||||
|
||||
def self.model
|
||||
PlaceholderUser
|
||||
end
|
||||
|
||||
validate :user_allowed_to_modify
|
||||
|
||||
protected
|
||||
|
||||
##
|
||||
# Placeholder users can only be updated by Admins
|
||||
def user_allowed_to_modify
|
||||
unless user.admin? && user.active?
|
||||
errors.add :base, :error_unauthorized
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module PlaceholderUsers
|
||||
class CreateContract < BaseContract
|
||||
attribute :type
|
||||
|
||||
validate :type_is_placeholder_user
|
||||
|
||||
private
|
||||
|
||||
def type_is_placeholder_user
|
||||
unless model.type == PlaceholderUser.name
|
||||
errors.add(:type, 'Type and class mismatch')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module PlaceholderUsers
|
||||
class DeleteContract < ::DeleteContract
|
||||
delete_permission -> {
|
||||
self.class.deletion_allowed?(user)
|
||||
}
|
||||
|
||||
##
|
||||
# Checks if a given user may be deleted by another one.
|
||||
#
|
||||
# @param actor [User] User who wants to delete the given placeholder user.
|
||||
def self.deletion_allowed?(actor)
|
||||
actor.admin? && actor.active?
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
##
|
||||
# PlaceholderUsers can only be deleted by Admins
|
||||
def user_allowed_to_modify
|
||||
unless deletion_allowed?
|
||||
errors.add :base, :error_unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
def deletion_allowed?
|
||||
self.class.deletion_allowed? user
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module PlaceholderUsers
|
||||
class UpdateContract < BaseContract
|
||||
end
|
||||
end
|
||||
@@ -28,9 +28,9 @@
|
||||
|
||||
module Projects
|
||||
class ArchiveContract < ModelContract
|
||||
include RequiresAdminGuard
|
||||
include Projects::Archiver
|
||||
|
||||
validate :validate_admin_only
|
||||
validate :validate_no_foreign_wp_references
|
||||
|
||||
protected
|
||||
|
||||
@@ -28,12 +28,6 @@
|
||||
|
||||
module Projects
|
||||
module Archiver
|
||||
def validate_admin_only
|
||||
unless user.admin?
|
||||
errors.add :base, :error_unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
# Check that there is no wp of a non descendant project that is assigned
|
||||
# to one of the project or descendant versions
|
||||
def validate_no_foreign_wp_references
|
||||
|
||||
@@ -135,7 +135,7 @@ module Projects
|
||||
def validate_changing_active
|
||||
return unless model.active_changed?
|
||||
|
||||
validate_admin_only
|
||||
RequiresAdminGuard.validate_admin_only(user, errors)
|
||||
|
||||
if model.active?
|
||||
# switched to active -> unarchiving
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
|
||||
module Projects
|
||||
class UnarchiveContract < ModelContract
|
||||
include RequiresAdminGuard
|
||||
include Projects::Archiver
|
||||
|
||||
validate :validate_admin_only
|
||||
validate :validate_all_ancestors_active
|
||||
|
||||
protected
|
||||
|
||||
@@ -28,11 +28,8 @@
|
||||
# See docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'model_contract'
|
||||
|
||||
module Users
|
||||
class BaseContract < ::ModelContract
|
||||
attribute :type
|
||||
attribute :login
|
||||
attribute :firstname
|
||||
attribute :lastname
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
# See docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'users/base_contract'
|
||||
|
||||
module Users
|
||||
class CreateContract < BaseContract
|
||||
attribute :type
|
||||
|
||||
attribute :status do
|
||||
unless model.active? || model.invited?
|
||||
# New users may only have these two statuses
|
||||
@@ -41,6 +41,7 @@ module Users
|
||||
|
||||
validate :user_allowed_to_add
|
||||
validate :authentication_defined
|
||||
validate :type_is_user
|
||||
|
||||
private
|
||||
|
||||
@@ -59,5 +60,11 @@ module Users
|
||||
errors.add :base, :error_unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
def type_is_user
|
||||
unless model.type == User.name
|
||||
errors.add(:type, 'Type and class mismatch')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
# See docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'users/base_contract'
|
||||
|
||||
module Users
|
||||
class DeleteContract < ::DeleteContract
|
||||
delete_permission -> {
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
# See docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'users/base_contract'
|
||||
|
||||
module Users
|
||||
class UpdateContract < BaseContract
|
||||
validate :user_allowed_to_update
|
||||
|
||||
@@ -67,7 +67,7 @@ class MessagesController < ApplicationController
|
||||
@message = Messages::SetAttributesService
|
||||
.new(user: current_user,
|
||||
model: Message.new,
|
||||
contract_class: NoopContract)
|
||||
contract_class: EmptyContract)
|
||||
.call(forum: @forum)
|
||||
.result
|
||||
end
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class PlaceholderUsers::MembershipsController < ApplicationController
|
||||
include IndividualPrincipals::MembershipControllerMethods
|
||||
layout 'admin'
|
||||
|
||||
before_action :require_admin
|
||||
before_action :find_individual_principal
|
||||
|
||||
def find_individual_principal
|
||||
@individual_principal = PlaceholderUser.find(params[:placeholder_user_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def redirected_to_tab(_membership)
|
||||
'memberships'
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,162 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class PlaceholderUsersController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
helper_method :gon
|
||||
|
||||
before_action :require_admin, except: [:show]
|
||||
before_action :find_placeholder_user, only: %i[show
|
||||
edit
|
||||
update
|
||||
destroy]
|
||||
before_action :check_if_deletion_allowed, only: [:destroy]
|
||||
|
||||
def index
|
||||
@placeholder_users = PlaceholderUsers::PlaceholderUserFilterCell.filter params
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
render layout: !request.xhr?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
# show projects based on current user visibility
|
||||
@memberships = @placeholder_user.memberships
|
||||
.visible(current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render layout: 'no_menu' }
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@placeholder_user = PlaceholderUsers::SetAttributesService
|
||||
.new(user: User.current,
|
||||
model: PlaceholderUser.new,
|
||||
contract_class: EmptyContract)
|
||||
.call({})
|
||||
.result
|
||||
end
|
||||
|
||||
def create
|
||||
service = PlaceholderUsers::CreateService.new(user: User.current)
|
||||
service_result = service.call(permitted_params.placeholder_user)
|
||||
@placeholder_user = service_result.result
|
||||
|
||||
if service_result.success?
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
flash[:notice] = I18n.t(:notice_successful_create)
|
||||
redirect_to(params[:continue] ? new_placeholder_user_path : edit_placeholder_user_path(@placeholder_user))
|
||||
end
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
render action: :new
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@membership ||= Member.new
|
||||
@individual_principal = @placeholder_user
|
||||
end
|
||||
|
||||
def update
|
||||
service_result = PlaceholderUsers::UpdateService
|
||||
.new(user: User.current,
|
||||
model: @placeholder_user)
|
||||
.call(permitted_params.placeholder_user)
|
||||
|
||||
if service_result.success?
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
flash[:notice] = I18n.t(:notice_successful_update)
|
||||
redirect_back(fallback_location: edit_placeholder_user_path(@placeholder_user))
|
||||
end
|
||||
end
|
||||
else
|
||||
@membership ||= Member.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
render action: :edit
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
Users::DeleteService.new(user: User.current,
|
||||
model: @placeholder_user)
|
||||
.call
|
||||
|
||||
flash[:notice] = I18n.t('account.deleted')
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to placeholder_users_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_placeholder_user
|
||||
@placeholder_user = PlaceholderUser.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def check_if_deletion_allowed
|
||||
render_404 unless PlaceholderUsers::DeleteService.deletion_allowed? @placeholder_user, User.current
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def default_breadcrumb
|
||||
if action_name == 'index'
|
||||
t('label_placeholder_user_plural')
|
||||
else
|
||||
ActionController::Base.helpers.link_to(t('label_placeholder_user_plural'),
|
||||
placeholder_users_path)
|
||||
end
|
||||
end
|
||||
|
||||
def show_local_breadcrumb
|
||||
current_user.admin?
|
||||
end
|
||||
end
|
||||
@@ -29,56 +29,14 @@
|
||||
#++
|
||||
|
||||
class Users::MembershipsController < ApplicationController
|
||||
include IndividualPrincipals::MembershipControllerMethods
|
||||
layout 'admin'
|
||||
|
||||
before_action :require_admin
|
||||
before_action :find_user
|
||||
before_action :find_individual_principal
|
||||
|
||||
def update
|
||||
update_or_create(request.patch?, :notice_successful_update)
|
||||
end
|
||||
|
||||
def create
|
||||
update_or_create(request.post?, :notice_successful_create)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@membership = @user.memberships.find(params[:id])
|
||||
tab = redirected_to_tab(@membership)
|
||||
|
||||
if @membership.deletable? && request.delete?
|
||||
@membership.destroy
|
||||
@membership = nil
|
||||
|
||||
flash[:notice] = I18n.t(:notice_successful_delete)
|
||||
end
|
||||
|
||||
redirect_to controller: '/users', action: 'edit', id: @user, tab: tab
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_or_create(save_record, message)
|
||||
@membership = params[:id].present? ? Member.find(params[:id]) : Member.new(principal: @user, project: nil)
|
||||
|
||||
result = ::Members::EditMembershipService
|
||||
.new(@membership, save: save_record, current_user: current_user)
|
||||
.call(attributes: permitted_params.membership)
|
||||
|
||||
if result.success?
|
||||
flash[:notice] = I18n.t(message)
|
||||
else
|
||||
flash[:error] = result.errors.full_messages.join("\n")
|
||||
end
|
||||
|
||||
redirect_to controller: '/users',
|
||||
action: 'edit',
|
||||
id: @user,
|
||||
tab: redirected_to_tab(@membership)
|
||||
end
|
||||
|
||||
def find_user
|
||||
@user = User.find(params[:user_id])
|
||||
def find_individual_principal
|
||||
@individual_principal = User.find(params[:user_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
@@ -126,6 +126,7 @@ class UsersController < ApplicationController
|
||||
def edit
|
||||
@auth_sources = AuthSource.all
|
||||
@membership ||= Member.new
|
||||
@individual_principal = @user
|
||||
end
|
||||
|
||||
def update
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module IndividualPrincipalHooksHelper
|
||||
def call_individual_principals_memberships_hook(individual_principal, suffix, context = {})
|
||||
call_context = { individual_principal_key(individual_principal) => individual_principal }.merge(context)
|
||||
call_hook("view_#{individual_principal.class.name.underscore.pluralize}_memberships_table_#{suffix}".to_sym, call_context)
|
||||
end
|
||||
|
||||
def individual_principal_key(individual_principal)
|
||||
individual_principal.class.name.underscore.to_sym
|
||||
end
|
||||
end
|
||||
@@ -183,6 +183,10 @@ class PermittedParams
|
||||
permitted_params.merge(custom_field_values(:user))
|
||||
end
|
||||
|
||||
def placeholder_user
|
||||
params.require(:placeholder_user).permit(*self.class.permitted_attributes[:placeholder_user])
|
||||
end
|
||||
|
||||
def my_account_settings
|
||||
user.merge(pref: pref)
|
||||
end
|
||||
@@ -525,6 +529,9 @@ class PermittedParams
|
||||
:client_credentials_user_id,
|
||||
{ scopes: [] }
|
||||
],
|
||||
placeholder_user: %i(
|
||||
name
|
||||
),
|
||||
project_type: [
|
||||
:name,
|
||||
{ type_ids: [] }
|
||||
|
||||
@@ -33,6 +33,7 @@ class PlaceholderUser < Principal
|
||||
|
||||
validates_presence_of(:name)
|
||||
validates_uniqueness_of(:name)
|
||||
validates_length_of :name, maximum: 256
|
||||
|
||||
include ::Associations::Groupable
|
||||
|
||||
|
||||
@@ -76,6 +76,31 @@ class Principal < ApplicationRecord
|
||||
scope :not_in_project, ->(project) {
|
||||
where.not(id: Member.of(project).select(:user_id))
|
||||
}
|
||||
|
||||
scope :in_group, ->(group) {
|
||||
within_group(group)
|
||||
}
|
||||
|
||||
scope :not_in_group, ->(group) {
|
||||
within_group(group, false)
|
||||
}
|
||||
|
||||
scope :within_group, ->(group, positive = true) {
|
||||
group_id = group.is_a?(Group) ? [group.id] : Array(group).map(&:to_i)
|
||||
|
||||
sql_condition = group_id.any? ? 'WHERE gu.group_id IN (?)' : ''
|
||||
sql_not = positive ? '' : 'NOT'
|
||||
|
||||
sql_query = [
|
||||
"#{User.table_name}.id #{sql_not} IN " \
|
||||
"(SELECT gu.user_id FROM #{table_name_prefix}group_users#{table_name_suffix} gu #{sql_condition})"
|
||||
]
|
||||
if group_id.any?
|
||||
sql_query.push group_id
|
||||
end
|
||||
|
||||
where(sql_query)
|
||||
}
|
||||
|
||||
before_create :set_default_empty_values
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#-- encoding: UTF-8
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::IndividualPrincipals::Orders::GroupOrder < Queries::BaseOrder
|
||||
self.model = Principal
|
||||
|
||||
def self.key
|
||||
:group
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order
|
||||
order_string = "groups_users.lastname"
|
||||
|
||||
order_string += " DESC" if direction == :desc
|
||||
|
||||
model.order(order_string)
|
||||
end
|
||||
|
||||
def joins
|
||||
:groups
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::IndividualPrincipals::Orders::NameOrder < Queries::BaseOrder
|
||||
self.model = Principal
|
||||
|
||||
def self.key
|
||||
:name
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order
|
||||
ordered = model.order_by_name
|
||||
|
||||
if direction == :desc
|
||||
ordered = ordered.reverse_order
|
||||
end
|
||||
|
||||
ordered
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module Queries::PlaceholderUsers
|
||||
Queries::Register.filter Queries::PlaceholderUsers::PlaceholderUserQuery,
|
||||
Queries::PlaceholderUsers::Filters::NameFilter
|
||||
|
||||
Queries::Register.filter Queries::PlaceholderUsers::PlaceholderUserQuery,
|
||||
Queries::PlaceholderUsers::Filters::AnyNameAttributeFilter
|
||||
|
||||
Queries::Register.filter Queries::PlaceholderUsers::PlaceholderUserQuery,
|
||||
Queries::PlaceholderUsers::Filters::GroupFilter
|
||||
|
||||
Queries::Register.order Queries::PlaceholderUsers::PlaceholderUserQuery,
|
||||
Queries::PlaceholderUsers::Orders::DefaultOrder
|
||||
|
||||
Queries::Register.order Queries::PlaceholderUsers::PlaceholderUserQuery,
|
||||
Queries::PlaceholderUsers::Orders::NameOrder
|
||||
|
||||
Queries::Register.order Queries::PlaceholderUsers::PlaceholderUserQuery,
|
||||
Queries::PlaceholderUsers::Orders::GroupOrder
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::PlaceholderUsers::Filters::AnyNameAttributeFilter < Queries::PlaceholderUsers::Filters::NameFilter
|
||||
include Queries::Filters::Shared::AnyUserNameAttributeFilter
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::PlaceholderUsers::Filters::GroupFilter < Queries::PlaceholderUsers::Filters::PlaceholderUserFilter
|
||||
include Queries::Filters::Shared::GroupFilter
|
||||
|
||||
self.model = PlaceholderUser
|
||||
|
||||
def human_name
|
||||
PlaceholderUser.human_attribute_name(name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def group_subselect
|
||||
PlaceholderUser.in_group(values).select(:id).to_sql
|
||||
end
|
||||
|
||||
def any_group_subselect
|
||||
PlaceholderUser.within_group([]).select(:id).to_sql
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::PlaceholderUsers::Filters::NameFilter < Queries::PlaceholderUsers::Filters::PlaceholderUserFilter
|
||||
include Queries::Filters::Shared::UserNameFilter
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::PlaceholderUsers::Filters::PlaceholderUserFilter < Queries::Filters::Base
|
||||
self.model = PlaceholderUser
|
||||
|
||||
def human_name
|
||||
User.human_attribute_name(name)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::PlaceholderUsers::Orders::DefaultOrder < Queries::BaseOrder
|
||||
self.model = PlaceholderUser
|
||||
|
||||
def self.key
|
||||
/\A(id|name)\z/
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::PlaceholderUsers::Orders::GroupOrder < Queries::IndividualPrincipals::Orders::GroupOrder
|
||||
self.model = PlaceholderUser
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::PlaceholderUsers::Orders::NameOrder < Queries::IndividualPrincipals::Orders::NameOrder
|
||||
self.model = PlaceholderUser
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::PlaceholderUsers::PlaceholderUserQuery < Queries::BaseQuery
|
||||
def self.model
|
||||
PlaceholderUser
|
||||
end
|
||||
end
|
||||
@@ -28,24 +28,6 @@
|
||||
# See docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class Queries::Users::Orders::GroupOrder < Queries::BaseOrder
|
||||
class Queries::Users::Orders::GroupOrder < Queries::IndividualPrincipals::Orders::GroupOrder
|
||||
self.model = User
|
||||
|
||||
def self.key
|
||||
:group
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order
|
||||
order_string = "groups_users.lastname"
|
||||
|
||||
order_string += " DESC" if direction == :desc
|
||||
|
||||
model.order(order_string)
|
||||
end
|
||||
|
||||
def joins
|
||||
:groups
|
||||
end
|
||||
end
|
||||
|
||||
@@ -137,26 +137,6 @@ class User < Principal
|
||||
before_destroy :delete_associated_private_queries
|
||||
before_destroy :reassign_associated
|
||||
|
||||
scope :in_group, ->(group) {
|
||||
within_group(group)
|
||||
}
|
||||
scope :not_in_group, ->(group) {
|
||||
within_group(group, false)
|
||||
}
|
||||
scope :within_group, ->(group, positive = true) {
|
||||
group_id = group.is_a?(Group) ? [group.id] : Array(group).map(&:to_i)
|
||||
|
||||
sql_condition = group_id.any? ? 'WHERE gu.group_id IN (?)' : ''
|
||||
sql_not = positive ? '' : 'NOT'
|
||||
|
||||
sql_query = ["#{User.table_name}.id #{sql_not} IN (SELECT gu.user_id FROM #{table_name_prefix}group_users#{table_name_suffix} gu #{sql_condition})"]
|
||||
if group_id.any?
|
||||
sql_query.push group_id
|
||||
end
|
||||
|
||||
where(sql_query)
|
||||
}
|
||||
|
||||
scope :admin, -> { where(admin: true) }
|
||||
|
||||
def self.unique_attribute
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class PlaceholderUsers::CreateService < ::BaseServices::Create
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class PlaceholderUsers::DeleteService < ::BaseServices::Delete
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
module PlaceholderUsers
|
||||
class SetAttributesService < ::BaseServices::SetAttributes
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
class PlaceholderUsers::UpdateService < ::BaseServices::Update
|
||||
end
|
||||
+16
-12
@@ -6,7 +6,7 @@ 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) 2006-2017 Jean-Philippe Lang
|
||||
Copyright (C) 2010-2013 the ChiliProject Team
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
@@ -31,14 +31,14 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
|
||||
<div class="grid-block">
|
||||
<div class="grid-content">
|
||||
<% if @user.memberships.any? %>
|
||||
<% if @individual_principal.memberships.any? %>
|
||||
<div class="generic-table--container">
|
||||
<div class="generic-table--results-container">
|
||||
<table class="generic-table memberships">
|
||||
<colgroup>
|
||||
<col highlight-col>
|
||||
<col highlight-col>
|
||||
<%= call_hook(:view_users_memberships_table_colgroup, user: @user )%>
|
||||
<%= call_individual_principals_memberships_hook(@individual_principal, 'colgroup') %>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead>
|
||||
@@ -61,12 +61,12 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<%= call_hook(:view_users_memberships_table_header, user: @user )%>
|
||||
<%= call_individual_principals_memberships_hook(@individual_principal, 'header') %>
|
||||
<th><div class="generic-table--empty-header"></div></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @user.memberships.where.not(project: nil).each do |membership| %>
|
||||
<% @individual_principal.memberships.where.not(project: nil).each do |membership| %>
|
||||
<% next if membership.new_record? %>
|
||||
<tr id="member-<%= membership.id %>" class="member">
|
||||
<td class="project">
|
||||
@@ -78,7 +78,7 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
<%=h membership.roles.sort.collect(&:to_s).join(', ') %>
|
||||
</span>
|
||||
<%= labelled_tabular_form_for(:membership,
|
||||
url: user_membership_path(user_id: @user, id: membership),
|
||||
url: polymorphic_path([@individual_principal, :membership], id: membership),
|
||||
html: { id: "member-#{membership.id}-roles-form",
|
||||
class: "member-#{membership.id}--edit-toggle-item",
|
||||
style: 'display:none;'},
|
||||
@@ -98,20 +98,24 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
<p><%= submit_tag t(:button_change), class: 'user-memberships--edit-submit-button button -highlight -small' %>
|
||||
<p><%= submit_tag t(:button_change), class: 'memberships--edit-submit-button button -highlight -small' %>
|
||||
<%= link_to_function t(:button_cancel),
|
||||
"jQuery('.member-#{membership.id}--edit-toggle-item').toggle();",
|
||||
class: 'button -small' %></p>
|
||||
<% end %>
|
||||
</td>
|
||||
<%= call_hook(:view_users_memberships_table_row, user: @user, membership: membership, roles: roles, projects: projects )%>
|
||||
<%= call_individual_principals_memberships_hook(@individual_principal,
|
||||
'row',
|
||||
membership: membership,
|
||||
roles: roles,
|
||||
projects: projects) %>
|
||||
<td class="buttons">
|
||||
<%= link_to_function icon_wrapper('icon icon-edit', t(:button_edit)),
|
||||
"jQuery('.member-#{membership.id}--edit-toggle-item').toggle();",
|
||||
class: "member-#{membership.id}--edit-toggle-item user-memberships--edit-button",
|
||||
class: "member-#{membership.id}--edit-toggle-item memberships--edit-button",
|
||||
title: t(:button_edit) %>
|
||||
<%= link_to(icon_wrapper('icon icon-remove', t(:button_remove)),
|
||||
user_membership_path(user_id: @user, id: membership),
|
||||
polymorphic_path([@individual_principal, :membership], id: membership),
|
||||
method: :delete,
|
||||
title: t(:button_remove)) if membership.deletable? %>
|
||||
</td>
|
||||
@@ -129,11 +133,11 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
<div class="grid-content">
|
||||
<% if projects.any? %>
|
||||
<%= labelled_tabular_form_for(:membership,
|
||||
url: user_memberships_path(user_id: @user),
|
||||
url: polymorphic_path([@individual_principal, :memberships]),
|
||||
html: {id: "new_project_membership"}) do %>
|
||||
<fieldset class="form--fieldset">
|
||||
<legend class="form--fieldset-legend"><%=t(:label_project_new)%></legend>
|
||||
<%= styled_select_tag 'membership[project_id]', options_for_membership_project_select(@user, projects) %>
|
||||
<%= styled_select_tag 'membership[project_id]', options_for_membership_project_select(@individual_principal, projects) %>
|
||||
<div class="form--field -vertical">
|
||||
<%= styled_label_tag nil, "#{t(:label_role_plural)}:" %>
|
||||
<div class="form--field-container -vertical">
|
||||
@@ -0,0 +1,38 @@
|
||||
<%#-- copyright
|
||||
OpenProject is an open source project management software.
|
||||
Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
<%= error_messages_for 'placeholder_user' %>
|
||||
|
||||
<!--[form:placeholder_user]-->
|
||||
<section class="form--section">
|
||||
<div class="form--field -required"><%= f.text_field :name, label: t('label_name'), required: true, container_class: '-middle' %></div>
|
||||
|
||||
<%= call_hook(:view_placeholder_users_form, placeholder_user: @placeholder_user, form: f) %>
|
||||
</section>
|
||||
<!--[eoform:placeholder_user]-->
|
||||
@@ -0,0 +1,40 @@
|
||||
<%#-- copyright
|
||||
OpenProject is an open source project management software.
|
||||
Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
<%= labelled_tabular_form_for @placeholder_user,
|
||||
url: { controller: '/placeholder_users',
|
||||
action: "update",
|
||||
tab: nil },
|
||||
html: { method: :put,
|
||||
autocomplete: 'off' },
|
||||
as: :placeholder_user do |f| %>
|
||||
<%= render partial: 'form', locals: { f: f } %>
|
||||
|
||||
<%= styled_button_tag t(:button_save), class: '-highlight -with-icon icon-checkmark' %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,38 @@
|
||||
<%#-- copyright
|
||||
OpenProject is an open source project management software.
|
||||
Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
|
||||
++#%>
|
||||
<%= breadcrumb_toolbar(@placeholder_user.new_record? ? t(:label_placeholder_user_new) : @placeholder_user.name) do %>
|
||||
<% unless @placeholder_user.new_record? %>
|
||||
<li class="toolbar-item">
|
||||
<%= link_to placeholder_user_path(@placeholder_user), class: 'button' do %>
|
||||
<%= op_icon('button--icon icon-user') %>
|
||||
<span class="button--text"><%= t(:label_profile) %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,36 @@
|
||||
<%#-- copyright
|
||||
OpenProject is an open source project management software.
|
||||
Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
|
||||
<% html_title(t(:label_administration), "#{t(:label_edit)} #{PlaceholderUser.model_name.human} #{h(@placeholder_user.name)}") -%>
|
||||
|
||||
<% local_assigns[:additional_breadcrumb] = @placeholder_user.name %>
|
||||
<%= render partial: 'toolbar', locals: { new_user: false, :@placeholder_user => @placeholder_user } %>
|
||||
|
||||
<%= render_extensible_tabs :placeholder_user, placeholder_user: @placeholder_user %>
|
||||
@@ -0,0 +1,46 @@
|
||||
<%#-- copyright
|
||||
OpenProject is an open source project management software.
|
||||
Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
|
||||
++#%>
|
||||
<% html_title t(:label_administration), t(:label_placeholder_user_plural) -%>
|
||||
|
||||
<%= toolbar title: t(:label_placeholder_user_plural), title_class: 'no-padding-bottom' do %>
|
||||
<li class="toolbar-item">
|
||||
<%= link_to new_placeholder_user_path,
|
||||
{ class: 'button -alt-highlight',
|
||||
aria: { label: t(:label_placeholder_user_new) },
|
||||
title: t(:label_placeholder_user_new) } do %>
|
||||
<%= op_icon('button--icon icon-add') %>
|
||||
<span class="button--text"><%= t('activerecord.models.placeholder_user') %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<%= call_hook(:placeholder_user_admin_action_menu) %>
|
||||
<% end %>
|
||||
|
||||
<%= cell PlaceholderUsers::PlaceholderUserFilterCell, params %>
|
||||
|
||||
<%= cell PlaceholderUsers::TableCell, @placeholder_users, project: @project, current_user: current_user %>
|
||||
@@ -0,0 +1,44 @@
|
||||
<%#-- copyright
|
||||
OpenProject is an open source project management software.
|
||||
Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
<% html_title t(:label_administration), t("label_placeholder_user_new") %>
|
||||
<% local_assigns[:additional_breadcrumb] = t(:label_placeholder_user_new) %>
|
||||
<%= render partial: 'toolbar', locals: { new_user: true,
|
||||
:@placeholder_user => @placeholder_user } %>
|
||||
<%= labelled_tabular_form_for @placeholder_user,
|
||||
url: { action: "create" },
|
||||
html: { class: nil, autocomplete: 'off' },
|
||||
as: :placeholder_user do |f| %>
|
||||
<%= render partial: 'form', locals: { f: f, placeholder_user: @placeholder_user } %>
|
||||
|
||||
<p>
|
||||
<%= styled_button_tag t(:button_create), class: '-highlight -with-icon icon-checkmark' %>
|
||||
<%= styled_button_tag t(:button_create_and_continue), name: 'continue', class: '-highlight -with-icon icon-checkmark' %>
|
||||
</p>
|
||||
<% end %>
|
||||
@@ -0,0 +1,66 @@
|
||||
<%#-- copyright
|
||||
OpenProject is an open source project management software.
|
||||
Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= call_hook :placeholder_users_show_head %>
|
||||
<% end %>
|
||||
<% html_title t(:label_administration), t(:label_placeholder_user_plural) -%>
|
||||
<%= toolbar title: "#{avatar @placeholder_user} #{h(@placeholder_user.name)}".html_safe do %>
|
||||
<% if User.current.admin? %>
|
||||
<li class="toolbar-item">
|
||||
<%= link_to edit_placeholder_user_path(@placeholder_user), class: 'button', accesskey: accesskey(:edit) do %>
|
||||
<%= op_icon('button--icon icon-edit') %>
|
||||
<span class="button--text"><%= t(:button_edit) %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="grid-block medium-up-2">
|
||||
<div class="grid-content">
|
||||
<%= call_hook :view_account_left_top, placeholder_user: @placeholder_user %>
|
||||
|
||||
<%= call_hook :view_account_left_middle, placeholder_user: @placeholder_user %>
|
||||
|
||||
<% unless @memberships.empty? %>
|
||||
<h3><%=t(:label_project_plural)%></h3>
|
||||
<ul>
|
||||
<% for membership in @memberships %>
|
||||
<li>
|
||||
<%= link_to_project(membership.project) %>
|
||||
(<%=h membership.roles.sort.collect(&:to_s).join(', ') %>, <%= format_date(membership.created_at) %>)
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<%= call_hook :view_account_left_bottom, placeholder_user: @placeholder_user %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% html_title h(@placeholder_user.name) %>
|
||||
@@ -44,8 +44,8 @@ See docs/COPYRIGHT.rdoc for more details.
|
||||
<li class="toolbar-item">
|
||||
<%= link_to new_user_path,
|
||||
{ class: 'button -alt-highlight',
|
||||
aria: {label: t(:label_user_new)},
|
||||
title: t(:label_user_new)} do %>
|
||||
aria: { label: t(:label_user_new) },
|
||||
title: t(:label_user_new) } do %>
|
||||
<%= op_icon('button--icon icon-add') %>
|
||||
<span class="button--text"><%= t('activerecord.models.user') %></span>
|
||||
<% end %>
|
||||
|
||||
@@ -155,6 +155,11 @@ Redmine::MenuManager.map :admin_menu do |menu|
|
||||
caption: :label_user_plural,
|
||||
parent: :users_and_permissions
|
||||
|
||||
menu.push :placeholder_users,
|
||||
{ controller: '/placeholder_users' },
|
||||
caption: :label_placeholder_user_plural,
|
||||
parent: :users_and_permissions
|
||||
|
||||
menu.push :groups,
|
||||
{ controller: '/groups' },
|
||||
if: Proc.new { User.current.admin? },
|
||||
|
||||
@@ -774,6 +774,7 @@ en:
|
||||
status: "Work package status"
|
||||
member: "Member"
|
||||
news: "News"
|
||||
placeholder_user: "Placeholder user"
|
||||
project: "Project"
|
||||
query: "Custom query"
|
||||
role:
|
||||
@@ -1535,6 +1536,7 @@ en:
|
||||
label_my_account_data: "My account data"
|
||||
label_my_projects: "My projects"
|
||||
label_my_queries: "My custom queries"
|
||||
label_name: "Name"
|
||||
label_never: "Never"
|
||||
label_new: "New"
|
||||
label_new_features: "New features"
|
||||
@@ -1584,6 +1586,9 @@ en:
|
||||
label_permissions: "Permissions"
|
||||
label_permissions_report: "Permissions report"
|
||||
label_personalize_page: "Personalize this page"
|
||||
label_placeholder_user: "Placeholder user"
|
||||
label_placeholder_user_new: "New placeholder user"
|
||||
label_placeholder_user_plural: "Placeholder users"
|
||||
label_planning: "Planning"
|
||||
label_please_login: "Please log in"
|
||||
label_plugins: "Plugins"
|
||||
|
||||
+10
-2
@@ -452,11 +452,11 @@ OpenProject::Application.routes.draw do
|
||||
|
||||
resources :activity, :activities, only: :index, controller: 'activities'
|
||||
|
||||
resources :users do
|
||||
resources :users, except: :edit do
|
||||
resources :memberships, controller: 'users/memberships', only: %i[update create destroy]
|
||||
|
||||
member do
|
||||
match '/edit/:tab' => 'users#edit', via: :get, as: 'tab_edit'
|
||||
get '/edit(/:tab)' => 'users#edit', as: 'edit'
|
||||
match '/change_status/:change_action' => 'users#change_status_info', via: :get, as: 'change_status_info'
|
||||
post :change_status
|
||||
post :resend_invitation
|
||||
@@ -464,6 +464,14 @@ OpenProject::Application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :placeholder_users, except: :edit do
|
||||
resources :memberships, controller: 'placeholder_users/memberships', only: %i[update create destroy]
|
||||
|
||||
member do
|
||||
get '/edit(/:tab)' => 'placeholder_users#edit', as: 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
# The show page of groups is public and thus moved out of the admin scope
|
||||
resources :groups, only: %i[show], as: :show_group
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
module IndividualPrincipals
|
||||
module MembershipControllerMethods
|
||||
def update
|
||||
update_or_create(request.patch?, :notice_successful_update)
|
||||
end
|
||||
|
||||
def create
|
||||
update_or_create(request.post?, :notice_successful_create)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@membership = @individual_principal.memberships.find(params[:id])
|
||||
tab = redirected_to_tab(@membership)
|
||||
|
||||
if @membership.deletable? && request.delete?
|
||||
@membership.destroy
|
||||
@membership = nil
|
||||
|
||||
flash[:notice] = I18n.t(:notice_successful_delete)
|
||||
end
|
||||
|
||||
redirect_to edit_polymorphic_path(@individual_principal, tab: tab)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_or_create(save_record, message)
|
||||
@membership = params[:id].present? ? Member.find(params[:id]) : Member.new(principal: @individual_principal, project: nil)
|
||||
|
||||
result = ::Members::EditMembershipService
|
||||
.new(@membership, save: save_record, current_user: current_user)
|
||||
.call(attributes: permitted_params.membership)
|
||||
|
||||
if result.success?
|
||||
flash[:notice] = I18n.t(message)
|
||||
else
|
||||
flash[:error] = result.errors.full_messages.join("\n")
|
||||
end
|
||||
|
||||
redirect_to edit_polymorphic_path(@individual_principal, tab: redirected_to_tab(@membership))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -34,7 +34,8 @@ module OpenProject
|
||||
class << self
|
||||
def tabs
|
||||
@tabs ||= {
|
||||
user: core_user_tabs
|
||||
user: core_user_tabs,
|
||||
placeholder_user: core_placeholder_user_tabs
|
||||
}
|
||||
end
|
||||
|
||||
@@ -60,32 +61,49 @@ module OpenProject
|
||||
{
|
||||
name: 'general',
|
||||
partial: 'users/general',
|
||||
path: ->(params) { tab_edit_user_path(params[:user], tab: :general) },
|
||||
path: ->(params) { edit_user_path(params[:user], tab: :general) },
|
||||
label: :label_general
|
||||
},
|
||||
{
|
||||
name: 'memberships',
|
||||
partial: 'users/memberships',
|
||||
path: ->(params) { tab_edit_user_path(params[:user], tab: :memberships) },
|
||||
partial: 'individual_principals/memberships',
|
||||
path: ->(params) { edit_user_path(params[:user], tab: :memberships) },
|
||||
label: :label_project_plural,
|
||||
only_if: ->(*) { User.current.admin? }
|
||||
},
|
||||
{
|
||||
name: 'groups',
|
||||
partial: 'users/groups',
|
||||
path: ->(params) { tab_edit_user_path(params[:user], tab: :groups) },
|
||||
path: ->(params) { edit_user_path(params[:user], tab: :groups) },
|
||||
label: :label_group_plural,
|
||||
only_if: ->(*) { User.current.admin? && Group.any? }
|
||||
},
|
||||
{
|
||||
name: 'global_roles',
|
||||
partial: 'users/global_roles',
|
||||
path: ->(params) { tab_edit_user_path(params[:user], tab: :global_roles) },
|
||||
path: ->(params) { edit_user_path(params[:user], tab: :global_roles) },
|
||||
label: :label_global_roles,
|
||||
only_if: ->(*) { User.current.admin? }
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def core_placeholder_user_tabs
|
||||
[
|
||||
{
|
||||
name: 'general',
|
||||
partial: 'placeholder_users/general',
|
||||
path: ->(params) { edit_placeholder_user_path(params[:placeholder_user], tab: :general) },
|
||||
label: :label_general
|
||||
},
|
||||
{
|
||||
name: 'memberships',
|
||||
partial: 'individual_principals/memberships',
|
||||
path: ->(params) { edit_placeholder_user_path(params[:placeholder_user], tab: :memberships) },
|
||||
label: :label_project_plural
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -51,7 +51,7 @@ module OpenProject::Avatars
|
||||
add_tab_entry :user,
|
||||
name: 'avatar',
|
||||
partial: 'avatars/users/avatar_tab',
|
||||
path: ->(params) { tab_edit_user_path(params[:user], tab: :avatar) },
|
||||
path: ->(params) { edit_user_path(params[:user], tab: :avatar) },
|
||||
label: :label_avatar,
|
||||
only_if: ->(*) { User.current.admin? && ::OpenProject::Avatars::AvatarManager.avatars_enabled? }
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ module Costs
|
||||
add_tab_entry :user,
|
||||
name: 'rates',
|
||||
partial: 'users/rates',
|
||||
path: ->(params) { tab_edit_user_path(params[:user], tab: :rates) },
|
||||
path: ->(params) { edit_user_path(params[:user], tab: :rates) },
|
||||
only_if: ->(*) { User.current.admin? },
|
||||
label: :caption_rate_history
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ OpenProject::Application::routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :users do
|
||||
resources :users, only: [] do
|
||||
member do
|
||||
resources :two_factor_devices,
|
||||
param: :device_id,
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ module OpenProject::TwoFactorAuthentication
|
||||
add_tab_entry :user,
|
||||
name: 'two_factor_authentication',
|
||||
partial: 'users/two_factor_authentication',
|
||||
path: ->(params) { tab_edit_user_path(params[:user], tab: :two_factor_authentication) },
|
||||
path: ->(params) { edit_user_path(params[:user], tab: :two_factor_authentication) },
|
||||
label: 'two_factor_authentication.label_two_factor_authentication',
|
||||
only_if: ->(*) { User.current.admin? && OpenProject::TwoFactorAuthentication::TokenStrategyManager.enabled? }
|
||||
|
||||
|
||||
@@ -27,27 +27,13 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe AttributeHelpTexts::BaseContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:model) { FactoryBot.build_stubbed :work_package_help_text }
|
||||
let(:contract) { described_class.new(model, current_user) }
|
||||
subject { contract.validate }
|
||||
|
||||
context 'as admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :admin }
|
||||
|
||||
it 'validates the contract' do
|
||||
expect(subject).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context 'as regular user' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :user }
|
||||
|
||||
it 'returns an error on validation' do
|
||||
expect(subject).to eq false
|
||||
expect(contract.errors.symbols_for(:base))
|
||||
.to match_array [:error_unauthorized]
|
||||
end
|
||||
end
|
||||
it_behaves_like 'contract is valid for active admin users only'
|
||||
end
|
||||
|
||||
@@ -29,27 +29,28 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe CustomActions::CuContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:user) { FactoryBot.build_stubbed(:user) }
|
||||
let(:action) do
|
||||
FactoryBot.build_stubbed(:custom_action, actions:
|
||||
[CustomActions::Actions::AssignedTo.new])
|
||||
end
|
||||
let(:instance) { described_class.new(action) }
|
||||
let(:contract) { described_class.new(action) }
|
||||
|
||||
describe 'name' do
|
||||
it 'is writable' do
|
||||
action.name = 'blubs'
|
||||
|
||||
expect(instance.validate)
|
||||
.to be_truthy
|
||||
expect_contract_valid
|
||||
end
|
||||
it 'needs to be set' do
|
||||
action.name = nil
|
||||
|
||||
expect(instance.validate)
|
||||
.to be_falsey
|
||||
expect_contract_invalid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -57,8 +58,7 @@ describe CustomActions::CuContract do
|
||||
it 'is writable' do
|
||||
action.description = 'blubs'
|
||||
|
||||
expect(instance.validate)
|
||||
.to be_truthy
|
||||
expect_contract_valid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -68,26 +68,19 @@ describe CustomActions::CuContract do
|
||||
|
||||
action.actions = [responsible_action]
|
||||
|
||||
expect(instance.validate)
|
||||
.to be_truthy
|
||||
expect_contract_valid
|
||||
end
|
||||
|
||||
it 'needs to have one' do
|
||||
action.actions = []
|
||||
|
||||
instance.validate
|
||||
|
||||
expect(instance.errors.symbols_for(:actions))
|
||||
.to eql [:empty]
|
||||
expect_contract_invalid actions: :empty
|
||||
end
|
||||
|
||||
it 'requires a value if the action requires one' do
|
||||
action.actions = [CustomActions::Actions::Status.new([])]
|
||||
|
||||
instance.validate
|
||||
|
||||
expect(instance.errors.symbols_for(:actions))
|
||||
.to eql [:empty]
|
||||
expect_contract_invalid actions: :empty
|
||||
end
|
||||
|
||||
it 'allows only the allowed values' do
|
||||
@@ -99,19 +92,13 @@ describe CustomActions::CuContract do
|
||||
|
||||
action.actions = [status_action]
|
||||
|
||||
instance.validate
|
||||
|
||||
expect(instance.errors.symbols_for(:actions))
|
||||
.to eql [:inclusion]
|
||||
expect_contract_invalid actions: :inclusion
|
||||
end
|
||||
|
||||
it 'is not allowed to have an inexistent action' do
|
||||
action.actions = [CustomActions::Actions::Inexistent.new]
|
||||
|
||||
instance.validate
|
||||
|
||||
expect(instance.errors.symbols_for(:actions))
|
||||
.to eql [:does_not_exist]
|
||||
expect_contract_invalid actions: :does_not_exist
|
||||
end
|
||||
end
|
||||
|
||||
@@ -119,7 +106,7 @@ describe CustomActions::CuContract do
|
||||
it 'is writable' do
|
||||
action.conditions = [double('some bogus condition', key: 'some', values: 'bogus', validate: true)]
|
||||
|
||||
expect(instance.validate)
|
||||
expect(contract.validate)
|
||||
.to be_truthy
|
||||
end
|
||||
|
||||
@@ -132,19 +119,13 @@ describe CustomActions::CuContract do
|
||||
|
||||
action.conditions = [status_condition]
|
||||
|
||||
instance.validate
|
||||
|
||||
expect(instance.errors.symbols_for(:conditions))
|
||||
.to eql [:inclusion]
|
||||
expect_contract_invalid conditions: :inclusion
|
||||
end
|
||||
|
||||
it 'is not allowed to have an inexistent condition' do
|
||||
action.conditions = [CustomActions::Conditions::Inexistent.new]
|
||||
|
||||
instance.validate
|
||||
|
||||
expect(instance.errors.symbols_for(:conditions))
|
||||
.to eql [:does_not_exist]
|
||||
expect_contract_invalid conditions: :does_not_exist
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -29,28 +29,15 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe CustomFields::CreateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:cf) { FactoryBot.build :project_custom_field }
|
||||
let(:contract) do
|
||||
described_class.new(cf, current_user, options: { changed_by_system: [] })
|
||||
end
|
||||
|
||||
describe 'as admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :admin }
|
||||
|
||||
it 'validates the contract' do
|
||||
expect(contract.validate).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'as regular user' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :user }
|
||||
|
||||
it 'invalidates the contract' do
|
||||
expect(contract.validate).to eq(false)
|
||||
expect(contract.errors.symbols_for(:base))
|
||||
.to match_array [:error_unauthorized]
|
||||
end
|
||||
end
|
||||
it_behaves_like 'contract is valid for active admin users only'
|
||||
end
|
||||
|
||||
@@ -29,28 +29,15 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe CustomFields::UpdateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:cf) { FactoryBot.build :project_custom_field }
|
||||
let(:contract) do
|
||||
described_class.new(cf, current_user, options: { changed_by_system: [] })
|
||||
end
|
||||
|
||||
describe 'as admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :admin }
|
||||
|
||||
it 'validates the contract' do
|
||||
expect(contract.validate).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'as regular user' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :user }
|
||||
|
||||
it 'invalidates the contract' do
|
||||
expect(contract.validate).to eq(false)
|
||||
expect(contract.errors.symbols_for(:base))
|
||||
.to match_array [:error_unauthorized]
|
||||
end
|
||||
end
|
||||
it_behaves_like 'contract is valid for active admin users only'
|
||||
end
|
||||
|
||||
@@ -28,8 +28,11 @@
|
||||
|
||||
require 'spec_helper'
|
||||
require_relative './shared_contract_examples'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe Members::CreateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
it_behaves_like 'member contract' do
|
||||
let(:member) do
|
||||
Member.new(project: member_project,
|
||||
@@ -37,31 +40,25 @@ describe Members::CreateContract do
|
||||
principal: member_principal)
|
||||
end
|
||||
|
||||
subject(:contract) { described_class.new(member, current_user) }
|
||||
let(:contract) { described_class.new(member, current_user) }
|
||||
|
||||
describe '#validation' do
|
||||
context 'if the principal is nil' do
|
||||
let(:member_principal) { nil }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, principal: %i(blank))
|
||||
end
|
||||
it_behaves_like 'contract is invalid', principal: :blank
|
||||
end
|
||||
|
||||
context 'if the principal is a builtin user' do
|
||||
let(:member_principal) { FactoryBot.build_stubbed(:anonymous) }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, principal: %i(unassignable))
|
||||
end
|
||||
it_behaves_like 'contract is invalid', principal: :unassignable
|
||||
end
|
||||
|
||||
context 'if the principal is a locked user' do
|
||||
let(:member_principal) { FactoryBot.build_stubbed(:locked_user) }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, principal: %i(unassignable))
|
||||
end
|
||||
it_behaves_like 'contract is invalid', principal: :unassignable
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,8 +28,12 @@
|
||||
|
||||
require 'spec_helper'
|
||||
require_relative './shared_contract_examples'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
|
||||
describe Members::UpdateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
it_behaves_like 'member contract' do
|
||||
let(:member) do
|
||||
FactoryBot.build_stubbed(:member,
|
||||
@@ -38,7 +42,7 @@ describe Members::UpdateContract do
|
||||
principal: member_principal)
|
||||
end
|
||||
|
||||
subject(:contract) { described_class.new(member, current_user) }
|
||||
let(:contract) { described_class.new(member, current_user) }
|
||||
|
||||
describe 'validation' do
|
||||
context 'if the principal is changed' do
|
||||
@@ -46,9 +50,7 @@ describe Members::UpdateContract do
|
||||
member.principal = FactoryBot.build_stubbed(:user)
|
||||
end
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, user_id: %i(error_readonly))
|
||||
end
|
||||
it_behaves_like 'contract is invalid', user_id: :error_readonly
|
||||
end
|
||||
|
||||
context 'if the project is changed' do
|
||||
@@ -56,17 +58,13 @@ describe Members::UpdateContract do
|
||||
member.project = FactoryBot.build_stubbed(:project)
|
||||
end
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, project_id: %i(error_readonly))
|
||||
end
|
||||
it_behaves_like 'contract is invalid', project_id: :error_readonly
|
||||
end
|
||||
|
||||
context 'if the principal is a locked user' do
|
||||
let(:member_principal) { FactoryBot.build_stubbed(:locked_user) }
|
||||
|
||||
it 'is valid' do
|
||||
expect_valid(true)
|
||||
end
|
||||
it_behaves_like 'contract is valid'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#-- encoding: UTF-8
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
require_relative 'shared_contract_examples'
|
||||
|
||||
describe PlaceholderUsers::CreateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
it_behaves_like 'placeholder user contract' do
|
||||
let(:placeholder_user) { PlaceholderUser.new(name: placeholder_user_name) }
|
||||
let(:contract) { described_class.new(placeholder_user, current_user) }
|
||||
let(:current_user) { FactoryBot.build_stubbed(:admin) }
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe PlaceholderUsers::DeleteContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:placeholder_user) { FactoryBot.build_stubbed(:placeholder_user) }
|
||||
let(:contract) { described_class.new(placeholder_user, current_user) }
|
||||
|
||||
it_behaves_like 'contract is valid for active admin users only'
|
||||
end
|
||||
@@ -0,0 +1,73 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
shared_examples_for 'placeholder user contract' do
|
||||
let(:placeholder_user_name) { 'UX Designer' }
|
||||
|
||||
it_behaves_like 'contract is valid for active admin users only'
|
||||
|
||||
context 'name' do
|
||||
context 'is valid' do
|
||||
it_behaves_like 'contract is valid'
|
||||
end
|
||||
|
||||
context 'is not too long' do
|
||||
let(:placeholder_user) { PlaceholderUser.new(name: 'X' * 257) }
|
||||
|
||||
it_behaves_like 'contract is invalid'
|
||||
end
|
||||
|
||||
context 'is not empty' do
|
||||
let(:placeholder_user) { PlaceholderUser.new(name: '') }
|
||||
|
||||
it_behaves_like 'contract is invalid'
|
||||
end
|
||||
|
||||
context 'is unique' do
|
||||
before do
|
||||
PlaceholderUser.create(name: placeholder_user_name)
|
||||
end
|
||||
|
||||
it_behaves_like 'contract is invalid'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'type' do
|
||||
context 'type and class mismatch' do
|
||||
before do
|
||||
placeholder_user.type = User.name
|
||||
end
|
||||
|
||||
it_behaves_like 'contract is invalid'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
#-- encoding: UTF-8
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
require_relative 'shared_contract_examples'
|
||||
|
||||
describe PlaceholderUsers::UpdateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
it_behaves_like 'placeholder user contract' do
|
||||
let(:placeholder_user) { FactoryBot.build_stubbed(:placeholder_user, name: placeholder_user_name) }
|
||||
let(:contract) { described_class.new(placeholder_user, current_user) }
|
||||
let(:current_user) { FactoryBot.build_stubbed(:admin) }
|
||||
end
|
||||
end
|
||||
@@ -29,34 +29,13 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe Projects::ArchiveContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:project) { FactoryBot.build_stubbed(:project) }
|
||||
let(:contract) { described_class.new(project, current_user) }
|
||||
|
||||
subject(:contract) { described_class.new(project, current_user) }
|
||||
|
||||
def expect_valid(valid, symbols = {})
|
||||
expect(contract.validate).to eq(valid)
|
||||
|
||||
symbols.each do |key, arr|
|
||||
expect(contract.errors.symbols_for(key)).to match_array arr
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :admin }
|
||||
|
||||
it 'is valid' do
|
||||
expect_valid(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :user }
|
||||
let(:permissions) { [] }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, base: %i(error_unauthorized))
|
||||
end
|
||||
end
|
||||
it_behaves_like 'contract is valid for active admin users only'
|
||||
end
|
||||
|
||||
@@ -29,37 +29,13 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe Projects::DeleteContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:project) { FactoryBot.build_stubbed(:project) }
|
||||
let(:contract) { described_class.new(project, current_user) }
|
||||
|
||||
subject(:contract) { described_class.new(project, current_user) }
|
||||
|
||||
def expect_valid(valid, symbols = {})
|
||||
expect(contract.validate).to eq(valid)
|
||||
|
||||
symbols.each do |key, arr|
|
||||
expect(contract.errors.symbols_for(key)).to match_array arr
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'is valid' do
|
||||
end
|
||||
|
||||
context 'when user is admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :admin }
|
||||
|
||||
it 'is valid' do
|
||||
expect_valid(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :user }
|
||||
let(:permissions) { [] }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, base: %i(error_unauthorized))
|
||||
end
|
||||
end
|
||||
it_behaves_like 'contract is valid for active admin users only'
|
||||
end
|
||||
|
||||
@@ -28,14 +28,17 @@
|
||||
|
||||
require 'spec_helper'
|
||||
require_relative './shared_contract_examples'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe Projects::InstantiateTemplateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:user) { FactoryBot.build_stubbed :user }
|
||||
let(:project) { Project.new name: 'Foo Bar', identifier: 'foo' }
|
||||
let(:template) { FactoryBot.build_stubbed :project }
|
||||
let(:options) { { template_project_id: template.id } }
|
||||
|
||||
subject { described_class.new(project, user, options: options) }
|
||||
let(:contract) { described_class.new(project, user, options: options) }
|
||||
|
||||
before do
|
||||
allow(user)
|
||||
@@ -52,19 +55,13 @@ describe Projects::InstantiateTemplateContract do
|
||||
let(:allowed_to_copy) { true }
|
||||
let(:allowed_to_add) { true }
|
||||
|
||||
it 'validates the contract' do
|
||||
expect(subject.validate).to eq true
|
||||
expect(subject.errors).to be_empty
|
||||
end
|
||||
it_behaves_like 'contract is valid'
|
||||
|
||||
context 'but may not add projects' do
|
||||
let(:allowed_to_copy) { true }
|
||||
let(:allowed_to_add) { false }
|
||||
|
||||
it 'fails the parent contract' do
|
||||
expect(subject.validate).to eq false
|
||||
expect(subject.errors[:base]).to include 'may not be accessed.'
|
||||
end
|
||||
it_behaves_like 'contract is invalid', base: :error_unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
@@ -72,9 +69,6 @@ describe Projects::InstantiateTemplateContract do
|
||||
let(:allowed_to_copy) { false }
|
||||
let(:allowed_to_add) { true }
|
||||
|
||||
it 'fails the contract' do
|
||||
expect(subject.validate).to eq false
|
||||
expect(subject.errors[:base]).to include 'may not be accessed.'
|
||||
end
|
||||
it_behaves_like 'contract is invalid', base: :error_unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
@@ -29,34 +29,13 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe Projects::UnarchiveContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:project) { FactoryBot.build_stubbed(:project) }
|
||||
let(:contract) { described_class.new(project, current_user) }
|
||||
|
||||
subject(:contract) { described_class.new(project, current_user) }
|
||||
|
||||
def expect_valid(valid, symbols = {})
|
||||
expect(contract.validate).to eq(valid)
|
||||
|
||||
symbols.each do |key, arr|
|
||||
expect(contract.errors.symbols_for(key)).to match_array arr
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :admin }
|
||||
|
||||
it 'is valid' do
|
||||
expect_valid(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed :user }
|
||||
let(:permissions) { [] }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, base: %i(error_unauthorized))
|
||||
end
|
||||
end
|
||||
it_behaves_like 'contract is valid for active admin users only'
|
||||
end
|
||||
|
||||
@@ -29,8 +29,11 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe Queries::UpdateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:project) { FactoryBot.build_stubbed :project }
|
||||
let(:query) do
|
||||
FactoryBot.build_stubbed(:query, project: project, is_public: public, user: user)
|
||||
@@ -44,21 +47,13 @@ describe Queries::UpdateContract do
|
||||
end
|
||||
end
|
||||
end
|
||||
subject(:contract) { described_class.new(query, current_user) }
|
||||
let(:contract) { described_class.new(query, current_user) }
|
||||
|
||||
before do
|
||||
# Assume project is always visible
|
||||
allow(contract).to receive(:project_visible?).and_return true
|
||||
end
|
||||
|
||||
def expect_valid(valid, symbols = {})
|
||||
expect(contract.validate).to eq(valid)
|
||||
|
||||
symbols.each do |key, arr|
|
||||
expect(contract.errors.symbols_for(key)).to match_array arr
|
||||
end
|
||||
end
|
||||
|
||||
describe 'private query' do
|
||||
let(:public) { false }
|
||||
|
||||
@@ -68,17 +63,13 @@ describe Queries::UpdateContract do
|
||||
context 'user has no permission to save' do
|
||||
let(:permissions) { %i(edit_work_packages) }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, base: %i(error_unauthorized))
|
||||
end
|
||||
it_behaves_like 'contract user is unauthorized'
|
||||
end
|
||||
|
||||
context 'user has permission to save' do
|
||||
let(:permissions) { %i(save_queries) }
|
||||
|
||||
it 'is valid' do
|
||||
expect_valid(true)
|
||||
end
|
||||
it_behaves_like 'contract is valid'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -86,9 +77,7 @@ describe Queries::UpdateContract do
|
||||
let(:user) { FactoryBot.build_stubbed :user }
|
||||
let(:permissions) { %i(save_queries) }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, base: %i(error_unauthorized))
|
||||
end
|
||||
it_behaves_like 'contract user is unauthorized'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -99,25 +88,19 @@ describe Queries::UpdateContract do
|
||||
context 'user has no permission to save' do
|
||||
let(:permissions) { %i(invalid_permission) }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, base: %i(error_unauthorized))
|
||||
end
|
||||
it_behaves_like 'contract user is unauthorized'
|
||||
end
|
||||
|
||||
context 'user has no permission to manage public' do
|
||||
let(:permissions) { %i(manage_public_queries) }
|
||||
|
||||
it 'is valid' do
|
||||
expect_valid(true)
|
||||
end
|
||||
it_behaves_like 'contract is valid'
|
||||
end
|
||||
|
||||
context 'user has permission to save only own' do
|
||||
let(:permissions) { %i(save_queries) }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, base: %i(error_unauthorized))
|
||||
end
|
||||
it_behaves_like 'contract user is unauthorized'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
shared_context 'ModelContract shared context' do
|
||||
def expect_contract_valid
|
||||
expect(contract.validate).to eq(true)
|
||||
end
|
||||
|
||||
def expect_contract_invalid(errors = {})
|
||||
expect(contract.validate).to eq(false)
|
||||
|
||||
errors.each do |key, error_symbols|
|
||||
expect(contract.errors.symbols_for(key)).to match_array Array(error_symbols)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'contract is valid' do
|
||||
it do
|
||||
expect_contract_valid
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'contract is invalid' do |errors = {}|
|
||||
it do
|
||||
expect_contract_invalid errors
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'contract user is unauthorized' do
|
||||
it do
|
||||
expect_contract_invalid base: :error_unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'contract is valid for active admin users only' do
|
||||
context 'when admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed(:admin) }
|
||||
|
||||
context 'when admin active' do
|
||||
it_behaves_like 'contract is valid'
|
||||
end
|
||||
|
||||
context 'when admin not active' do
|
||||
let(:current_user) { FactoryBot.build_stubbed(:admin, status: User.statuses[:locked]) }
|
||||
|
||||
it_behaves_like 'contract user is unauthorized'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed(:user) }
|
||||
|
||||
it_behaves_like 'contract user is unauthorized'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -29,30 +29,18 @@
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'contracts/shared/model_contract_shared_context'
|
||||
|
||||
describe Users::CreateContract do
|
||||
include_context 'ModelContract shared context'
|
||||
|
||||
let(:user) { FactoryBot.build_stubbed(:user) }
|
||||
|
||||
subject(:contract) { described_class.new(user, current_user) }
|
||||
|
||||
def expect_valid(valid, symbols = {})
|
||||
expect(contract.validate).to eq(valid)
|
||||
|
||||
symbols.each do |key, arr|
|
||||
expect(contract.errors.symbols_for(key)).to match_array arr
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'is valid' do
|
||||
it 'is valid' do
|
||||
expect_valid(true)
|
||||
end
|
||||
end
|
||||
let(:contract) { described_class.new(user, current_user) }
|
||||
|
||||
context 'when admin' do
|
||||
let(:current_user) { FactoryBot.build_stubbed(:admin) }
|
||||
|
||||
it_behaves_like 'is valid'
|
||||
it_behaves_like 'contract is valid'
|
||||
|
||||
describe 'requires a password set when active' do
|
||||
before do
|
||||
@@ -60,16 +48,14 @@ describe Users::CreateContract do
|
||||
user.activate
|
||||
end
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, password: %i(blank))
|
||||
end
|
||||
it_behaves_like 'contract is invalid', password: :blank
|
||||
|
||||
context 'when password is set' do
|
||||
before do
|
||||
user.password = user.password_confirmation = 'password!password!'
|
||||
end
|
||||
|
||||
it_behaves_like 'is valid'
|
||||
it_behaves_like 'contract is valid'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -84,7 +70,7 @@ describe Users::CreateContract do
|
||||
user.invite
|
||||
end
|
||||
|
||||
it_behaves_like 'is valid'
|
||||
it_behaves_like 'contract is valid'
|
||||
end
|
||||
|
||||
describe 'cannot set the password' do
|
||||
@@ -92,9 +78,7 @@ describe Users::CreateContract do
|
||||
user.password = user.password_confirmation = 'password!password!'
|
||||
end
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, password: %i(error_readonly))
|
||||
end
|
||||
it_behaves_like 'contract is invalid', password: :error_readonly
|
||||
end
|
||||
|
||||
describe 'can set the auth_source' do
|
||||
@@ -105,9 +89,7 @@ describe Users::CreateContract do
|
||||
user.auth_source = auth_source
|
||||
end
|
||||
|
||||
it 'is valid' do
|
||||
expect_valid(true)
|
||||
end
|
||||
it_behaves_like 'contract is valid'
|
||||
end
|
||||
|
||||
describe 'cannot set the identity url' do
|
||||
@@ -115,17 +97,14 @@ describe Users::CreateContract do
|
||||
user.identity_url = 'saml:123412foo'
|
||||
end
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, identity_url: %i(error_readonly))
|
||||
end
|
||||
it_behaves_like 'contract is invalid', identity_url: :error_readonly
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unauthorized user' do
|
||||
let(:current_user) { FactoryBot.build_stubbed(:user) }
|
||||
|
||||
it 'is invalid' do
|
||||
expect_valid(false, base: %i(error_unauthorized))
|
||||
end
|
||||
it_behaves_like 'contract user is unauthorized'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'work_package'
|
||||
|
||||
describe PlaceholderUsers::MembershipsController, type: :controller do
|
||||
shared_let(:admin) { FactoryBot.create :admin }
|
||||
|
||||
let(:placeholder_user) { FactoryBot.create(:placeholder_user) }
|
||||
let(:anonymous) { FactoryBot.create(:anonymous) }
|
||||
|
||||
describe 'update memberships' do
|
||||
let(:project) { FactoryBot.create(:project) }
|
||||
let(:role) { FactoryBot.create(:role) }
|
||||
|
||||
it 'works' do
|
||||
# i.e. it should successfully add a placeholder user to a project's members
|
||||
as_logged_in_user admin do
|
||||
post :create,
|
||||
params: {
|
||||
placeholder_user_id: placeholder_user.id,
|
||||
membership: {
|
||||
project_id: project.id,
|
||||
role_ids: [role.id]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
expect(response).to redirect_to(controller: '/placeholder_users',
|
||||
action: 'edit',
|
||||
id: placeholder_user.id,
|
||||
tab: 'memberships')
|
||||
|
||||
is_member = placeholder_user.reload.memberships.any? { |m|
|
||||
m.project_id == project.id && m.role_ids.include?(role.id)
|
||||
}
|
||||
expect(is_member).to eql(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,283 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
require 'work_package'
|
||||
|
||||
describe PlaceholderUsersController, type: :controller do
|
||||
let(:current_user) { FactoryBot.build(:admin) }
|
||||
let(:placeholder_user) { FactoryBot.create(:placeholder_user) }
|
||||
|
||||
shared_examples 'do not allow non-admins' do
|
||||
let(:current_user) { FactoryBot.build(:user) }
|
||||
|
||||
it 'responds with unauthorized status' do
|
||||
expect(response).to_not be_successful
|
||||
expect(response.status).to eq 403
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET new' do
|
||||
before do
|
||||
as_logged_in_user(current_user) do
|
||||
get :new
|
||||
end
|
||||
end
|
||||
|
||||
context 'as admin' do
|
||||
it 'renders the new template' do
|
||||
expect(response).to be_successful
|
||||
expect(response).to render_template 'placeholder_users/new'
|
||||
expect(assigns(:placeholder_user)).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
context 'not as admin' do
|
||||
let(:current_user) { FactoryBot.build(:user) }
|
||||
|
||||
it 'responds with unauthorized status' do
|
||||
expect(response).to_not be_successful
|
||||
expect(response.status).to eq 403
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET index' do
|
||||
before do
|
||||
as_logged_in_user(current_user) do
|
||||
get :index
|
||||
end
|
||||
end
|
||||
|
||||
context 'as admin' do
|
||||
it 'renders the index template' do
|
||||
expect(response).to be_successful
|
||||
expect(response).to render_template 'placeholder_users/index'
|
||||
expect(assigns(:placeholder_users)).to be_empty
|
||||
expect(assigns(:groups)).not_to be_present
|
||||
end
|
||||
end
|
||||
|
||||
context 'not as admin' do
|
||||
let(:current_user) { FactoryBot.build(:user) }
|
||||
|
||||
it_behaves_like 'do not allow non-admins'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET show' do
|
||||
shared_examples 'renders the show template' do
|
||||
it 'renders the show template' do
|
||||
expect(response).to be_successful
|
||||
expect(response).to render_template 'placeholder_users/show'
|
||||
expect(assigns(:placeholder_user)).to be_present
|
||||
expect(assigns(:memberships)).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
as_logged_in_user(current_user) do
|
||||
get :show, params: { id: placeholder_user.id }
|
||||
end
|
||||
end
|
||||
|
||||
context 'as admin' do
|
||||
it_behaves_like 'renders the show template'
|
||||
end
|
||||
|
||||
context 'not as admin' do
|
||||
let(:current_user) { FactoryBot.build(:user) }
|
||||
|
||||
# normal users can also checkout the profile page of placeholder user.
|
||||
it_behaves_like 'renders the show template'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET edit' do
|
||||
shared_examples 'renders the edit template' do
|
||||
it 'renders the show template' do
|
||||
expect(response).to be_successful
|
||||
expect(response).to render_template "placeholder_users/edit"
|
||||
expect(assigns(:placeholder_user)).to eql(placeholder_user)
|
||||
expect(assigns(:membership)).to be_present
|
||||
expect(assigns(:individual_principal)).to eql(placeholder_user)
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
as_logged_in_user(current_user) do
|
||||
get :edit, params: { id: placeholder_user.id }
|
||||
end
|
||||
end
|
||||
|
||||
context 'as admin' do
|
||||
it_behaves_like 'renders the edit template'
|
||||
end
|
||||
|
||||
context 'not as admin' do
|
||||
let(:current_user) { FactoryBot.build(:user) }
|
||||
|
||||
# normal users can also checkout the profile page of placeholder user.
|
||||
it_behaves_like 'do not allow non-admins'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST create' do
|
||||
let(:params) do
|
||||
{
|
||||
placeholder_user: {
|
||||
name: 'UX Developer'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
as_logged_in_user(current_user) do
|
||||
post :create, params: params
|
||||
end
|
||||
end
|
||||
|
||||
context 'as admin' do
|
||||
it 'should be assigned their new values' do
|
||||
user_from_db = PlaceholderUser.last
|
||||
expect(user_from_db.name).to eq('UX Developer')
|
||||
end
|
||||
|
||||
it 'should show a success notice' do
|
||||
expect(flash[:notice]).to eql(I18n.t(:notice_successful_create))
|
||||
end
|
||||
|
||||
it 'should not send an email' do
|
||||
expect(ActionMailer::Base.deliveries.empty?).to be_truthy
|
||||
end
|
||||
|
||||
context 'when user chose to directly create the next placeholder user' do
|
||||
let(:params) do
|
||||
{
|
||||
placeholder_user: {
|
||||
name: 'UX Developer'
|
||||
},
|
||||
continue: true
|
||||
}
|
||||
end
|
||||
|
||||
it 'should redirect to the new page' do
|
||||
expect(response).to redirect_to(new_placeholder_user_url)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user chose to NOT directly create the next placeholder user' do
|
||||
let(:params) do
|
||||
{
|
||||
placeholder_user: {
|
||||
name: 'UX Developer'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'should redirect to the edit page' do
|
||||
user_from_db = PlaceholderUser.last
|
||||
expect(response).to redirect_to(edit_placeholder_user_url(user_from_db))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'do not allow non-admins'
|
||||
|
||||
context 'invalid params' do
|
||||
let(:params) do
|
||||
{
|
||||
placeholder_user: {
|
||||
name: 'x' * 300 # Name is too long
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'should render the edit form with a validation error message' do
|
||||
expect(assigns(:'placeholder_user').errors.messages[:name].first).to include('is too long')
|
||||
expect(response).to render_template 'placeholder_users/new'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT update' do
|
||||
let(:params) do
|
||||
{
|
||||
id: placeholder_user.id,
|
||||
placeholder_user: {
|
||||
name: 'UX Guru'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
as_logged_in_user(current_user) do
|
||||
put :update, params: params
|
||||
end
|
||||
end
|
||||
|
||||
context 'as admin' do
|
||||
it 'should redirect to the edit page' do
|
||||
expect(response).to redirect_to(edit_placeholder_user_url(placeholder_user))
|
||||
end
|
||||
|
||||
it 'should be assigned their new values' do
|
||||
user_from_db = PlaceholderUser.find(placeholder_user.id)
|
||||
expect(user_from_db.name).to eq('UX Guru')
|
||||
end
|
||||
|
||||
it 'should not send an email' do
|
||||
expect(ActionMailer::Base.deliveries.empty?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'do not allow non-admins'
|
||||
|
||||
context 'invalid params' do
|
||||
let(:params) do
|
||||
{
|
||||
id: placeholder_user.id,
|
||||
placeholder_user: {
|
||||
name: 'x' * 300 # Name is too long
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'should render the edit form with a validation error message' do
|
||||
expect(assigns(:'placeholder_user').errors.messages[:name].first).to include('is too long')
|
||||
expect(response).to render_template 'placeholder_users/edit'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST destroy' do
|
||||
pending 'Admins can destroy placeholder users'
|
||||
pending 'Non admins cannot destroy placeholder users'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'create placeholder users', type: :feature, selenium: true do
|
||||
let(:current_user) { FactoryBot.create :admin }
|
||||
let(:new_placeholder_user_page) { Pages::NewPlaceholderUser.new }
|
||||
|
||||
before do
|
||||
allow(User).to receive(:current).and_return current_user
|
||||
end
|
||||
|
||||
shared_examples_for 'successful placeholder user creation' do
|
||||
it 'creates the placeholder user' do
|
||||
expect(page).to have_selector('.flash', text: 'Successful creation.')
|
||||
|
||||
new_placeholder_user = PlaceholderUser.order(Arel.sql('id DESC')).first
|
||||
|
||||
expect(current_path).to eql(edit_placeholder_user_path(new_placeholder_user.id))
|
||||
end
|
||||
end
|
||||
|
||||
context 'as admin' do
|
||||
before do
|
||||
visit new_placeholder_user_path
|
||||
|
||||
new_placeholder_user_page.fill_in! name: 'UX Designer'
|
||||
|
||||
perform_enqueued_jobs do
|
||||
new_placeholder_user_page.submit!
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'successful placeholder user creation'
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'edit placeholder users', type: :feature, js: true do
|
||||
let(:current_user) { FactoryBot.create :admin }
|
||||
let(:placeholder_user) { FactoryBot.create :placeholder_user, name: 'UX Developer' }
|
||||
|
||||
before do
|
||||
login_as current_user
|
||||
end
|
||||
|
||||
context 'as admin' do
|
||||
before do
|
||||
visit edit_placeholder_user_path(placeholder_user)
|
||||
end
|
||||
|
||||
it 'can edit name' do
|
||||
expect(page).to have_selector '#placeholder_user_name'
|
||||
|
||||
fill_in 'placeholder_user[name]', with: 'NewName', fill_options: { clear: :backspace }
|
||||
|
||||
click_on 'Save'
|
||||
|
||||
expect(page).to have_selector('.flash.notice', text: 'Successful update.')
|
||||
|
||||
placeholder_user.reload
|
||||
|
||||
expect(placeholder_user.name).to eq 'NewName'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,74 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'index placeholder users', type: :feature do
|
||||
let!(:current_user) { FactoryBot.create :admin }
|
||||
let!(:anonymous) { FactoryBot.create :anonymous }
|
||||
let!(:placeholder_user_1) do
|
||||
FactoryBot.create(:placeholder_user,
|
||||
name: 'One',
|
||||
created_at: 3.minute.ago)
|
||||
end
|
||||
let!(:placeholder_user_2) do
|
||||
FactoryBot.create(:placeholder_user,
|
||||
name: 'Two',
|
||||
created_at: 2.minute.ago)
|
||||
end
|
||||
let!(:placeholder_user_3) do
|
||||
FactoryBot.create(:placeholder_user,
|
||||
name: 'Three',
|
||||
created_at: 1.minute.ago)
|
||||
end
|
||||
let(:index_page) { Pages::Admin::PlaceholderUsers::Index.new }
|
||||
|
||||
before do
|
||||
login_as(current_user)
|
||||
end
|
||||
|
||||
it 'shows the placeholder users and allows filtering and ordering' do
|
||||
index_page.visit!
|
||||
|
||||
index_page.expect_not_listed(anonymous, current_user)
|
||||
|
||||
# Order is by id, asc
|
||||
# so first ones created are on top.
|
||||
index_page.expect_listed(placeholder_user_1, placeholder_user_2, placeholder_user_3)
|
||||
|
||||
index_page.order_by('Created on')
|
||||
index_page.expect_listed(placeholder_user_3, placeholder_user_2, placeholder_user_1)
|
||||
|
||||
index_page.order_by('Created on')
|
||||
index_page.expect_listed(placeholder_user_1, placeholder_user_2, placeholder_user_3)
|
||||
|
||||
index_page.filter_by_name(placeholder_user_3.name)
|
||||
index_page.expect_listed(placeholder_user_3)
|
||||
index_page.expect_not_listed(placeholder_user_1, placeholder_user_2)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,77 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
feature 'placeholder user memberships through placeholder user page', type: :feature, js: true do
|
||||
let!(:project) { FactoryBot.create :project, name: 'Project 1', identifier: 'project1' }
|
||||
let!(:project2) { FactoryBot.create :project, name: 'Project 2', identifier: 'project2' }
|
||||
let(:admin) { FactoryBot.create :admin }
|
||||
let(:placeholder_user) { FactoryBot.create :placeholder_user, name: 'UX Designer' }
|
||||
|
||||
let!(:manager) { FactoryBot.create :role, name: 'Manager' }
|
||||
let!(:developer) { FactoryBot.create :role, name: 'Developer' }
|
||||
|
||||
let(:placeholder_user_page) { Pages::Admin::IndividualPrincipals::Edit.new(placeholder_user) }
|
||||
|
||||
before do
|
||||
login_as(admin)
|
||||
|
||||
placeholder_user_page.visit!
|
||||
placeholder_user_page.open_projects_tab!
|
||||
end
|
||||
|
||||
scenario 'handles role modification flow' do
|
||||
placeholder_user_page.add_to_project! project.name, as: 'Manager'
|
||||
|
||||
member = placeholder_user.memberships.where(project_id: project.id).first
|
||||
placeholder_user_page.edit_roles!(member, %w(Manager Developer))
|
||||
|
||||
# Modify roles
|
||||
placeholder_user_page.expect_project(project.name)
|
||||
placeholder_user_page.expect_roles(project.name, %w(Manager Developer))
|
||||
|
||||
placeholder_user_page.expect_no_membership(project2.name)
|
||||
|
||||
# Remove all roles
|
||||
placeholder_user_page.expect_project(project.name)
|
||||
placeholder_user_page.edit_roles!(member, %w())
|
||||
|
||||
expect(page).to have_selector('.flash.error', text: 'Roles need to be assigned.')
|
||||
|
||||
# Remove the user from the project
|
||||
placeholder_user_page.remove_from_project!(project.name)
|
||||
placeholder_user_page.expect_no_membership(project.name)
|
||||
|
||||
# Re-add the user
|
||||
placeholder_user_page.add_to_project! project.name, as: %w(Manager Developer)
|
||||
|
||||
placeholder_user_page.expect_project(project.name)
|
||||
placeholder_user_page.expect_roles(project.name, %w(Manager Developer))
|
||||
end
|
||||
end
|
||||
@@ -37,9 +37,9 @@ describe 'index users', type: :feature do
|
||||
end
|
||||
|
||||
describe 'with some sortable users' do
|
||||
let!(:a_user) { FactoryBot.create :user, login: 'a_login', firstname: 'a_first', lastname: 'xxx_a' }
|
||||
let!(:b_user) { FactoryBot.create :user, login: 'b_login', firstname: 'b_first', lastname: 'nnn_b' }
|
||||
let!(:z_user) { FactoryBot.create :user, login: 'z_login', firstname: 'z_first', lastname: 'ccc_z' }
|
||||
let!(:a_user) { FactoryBot.create :user, login: 'aa_login', firstname: 'aa_first', lastname: 'xxx_a' }
|
||||
let!(:b_user) { FactoryBot.create :user, login: 'bb_login', firstname: 'bb_first', lastname: 'nnn_b' }
|
||||
let!(:z_user) { FactoryBot.create :user, login: 'zz_login', firstname: 'zz_first', lastname: 'ccc_z' }
|
||||
|
||||
it 'sorts them correctly (Regression #35012)' do
|
||||
index_page.visit!
|
||||
|
||||
@@ -36,7 +36,7 @@ feature 'user memberships through user page', type: :feature, js: true do
|
||||
let!(:manager) { FactoryBot.create :role, name: 'Manager' }
|
||||
let!(:developer) { FactoryBot.create :role, name: 'Developer' }
|
||||
|
||||
let(:user_page) { Pages::Admin::Users::Edit.new(admin.id) }
|
||||
let(:user_page) { Pages::Admin::IndividualPrincipals::Edit.new(admin) }
|
||||
|
||||
before do
|
||||
login_as(admin)
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe IndividualPrincipalHooksHelper, type: :helper do
|
||||
let(:user) { FactoryBot.build(:user) }
|
||||
let(:placeholder_user) { FactoryBot.build(:placeholder_user) }
|
||||
|
||||
describe '#individual_principal_key' do
|
||||
it 'returns the class name in underscore format' do
|
||||
expect(helper.individual_principal_key(user)).to eql(:user)
|
||||
expect(helper.individual_principal_key(placeholder_user)).to eql(:placeholder_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#call_individual_principals_memberships_hook' do
|
||||
context 'with user and without context' do
|
||||
before do
|
||||
expect(helper).to receive(:call_hook).with(:view_users_memberships_table_foo,
|
||||
user: user)
|
||||
end
|
||||
|
||||
it 'call call_hook with the correct arguments' do
|
||||
helper.call_individual_principals_memberships_hook(user, 'foo')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with placeholder user and without context' do
|
||||
before do
|
||||
expect(helper).to receive(:call_hook).with(:view_placeholder_users_memberships_table_foo,
|
||||
placeholder_user: placeholder_user)
|
||||
end
|
||||
|
||||
it 'call call_hook with the correct arguments' do
|
||||
helper.call_individual_principals_memberships_hook(placeholder_user, 'foo')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with user and with context' do
|
||||
before do
|
||||
expect(helper).to receive(:call_hook).with(:view_users_memberships_table_foo,
|
||||
user: user,
|
||||
yay: 'yo')
|
||||
end
|
||||
|
||||
it 'call call_hook with the correct arguments' do
|
||||
helper.call_individual_principals_memberships_hook(user, 'foo', yay: 'yo')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -34,7 +34,7 @@ describe TabsHelper, type: :helper do
|
||||
let(:given_tab) do
|
||||
{ name: 'avatar',
|
||||
partial: 'avatars/users/avatar_tab',
|
||||
path: ->(params) { tab_edit_user_path(params[:user], tab: :avatar) },
|
||||
path: ->(params) { edit_user_path(params[:user], tab: :avatar) },
|
||||
label: :label_avatar }
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Queries::PlaceholderUsers::PlaceholderUserQuery, type: :model do
|
||||
let(:instance) { described_class.new }
|
||||
let(:base_scope) { PlaceholderUser.order(id: :desc) }
|
||||
|
||||
context 'without a filter' do
|
||||
describe '#results' do
|
||||
it 'is the same as getting all the users' do
|
||||
expect(instance.results.to_sql).to eql base_scope.to_sql
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a name filter' do
|
||||
before do
|
||||
instance.where('name', '~', ['a user'])
|
||||
end
|
||||
|
||||
describe '#results' do
|
||||
it 'is the same as handwriting the query' do
|
||||
expected = base_scope
|
||||
.merge(PlaceholderUser
|
||||
.where(["LOWER(CONCAT(users.firstname, CONCAT(' ', users.lastname))) LIKE ?",
|
||||
"%a user%"]))
|
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql
|
||||
end
|
||||
end
|
||||
|
||||
describe '#valid?' do
|
||||
it 'is true' do
|
||||
expect(instance).to be_valid
|
||||
end
|
||||
|
||||
it 'is invalid if the filter is invalid' do
|
||||
instance.where('name', '=', [''])
|
||||
expect(instance).to be_invalid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a group filter' do
|
||||
let(:group_1) { FactoryBot.build_stubbed(:group) }
|
||||
|
||||
before do
|
||||
allow(Group)
|
||||
.to receive(:exists?)
|
||||
.and_return(true)
|
||||
|
||||
allow(Group)
|
||||
.to receive(:all)
|
||||
.and_return([group_1])
|
||||
|
||||
instance.where('group', '=', [group_1.id])
|
||||
end
|
||||
|
||||
describe '#results' do
|
||||
it 'is the same as handwriting the query' do
|
||||
expected = base_scope
|
||||
.merge(PlaceholderUser
|
||||
.where(["users.id IN (#{PlaceholderUser.in_group([group_1.id.to_s]).select(:id).to_sql})"]))
|
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql
|
||||
end
|
||||
end
|
||||
|
||||
describe '#valid?' do
|
||||
it 'is true' do
|
||||
expect(instance).to be_valid
|
||||
end
|
||||
|
||||
it 'is invalid if the filter is invalid' do
|
||||
instance.where('group', '=', [''])
|
||||
expect(instance).to be_invalid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a non existent filter' do
|
||||
before do
|
||||
instance.where('not_supposed_to_exist', '=', ['bogus'])
|
||||
end
|
||||
|
||||
describe '#results' do
|
||||
it 'returns a query not returning anything' do
|
||||
expected = PlaceholderUser.where(Arel::Nodes::Equality.new(1, 0))
|
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql
|
||||
end
|
||||
end
|
||||
|
||||
describe 'valid?' do
|
||||
it 'is false' do
|
||||
expect(instance).to be_invalid
|
||||
end
|
||||
|
||||
it 'returns the error on the filter' do
|
||||
instance.valid?
|
||||
|
||||
expect(instance.errors[:filters]).to eql ["Not supposed to exist does not exist."]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an id sortation' do
|
||||
before do
|
||||
instance.order(id: :asc)
|
||||
end
|
||||
|
||||
describe '#results' do
|
||||
it 'is the same as handwriting the query' do
|
||||
expected = PlaceholderUser.merge(PlaceholderUser.order(id: :asc))
|
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a name sortation' do
|
||||
before do
|
||||
instance.order(name: :desc)
|
||||
end
|
||||
|
||||
describe '#results' do
|
||||
it 'is the same as handwriting the query' do
|
||||
expected = "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"type\" = 'PlaceholderUser' ORDER BY \"users\".\"lastname\" DESC, \"users\".\"id\" DESC"
|
||||
|
||||
expect(instance.results.to_sql).to eql expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a group sortation' do
|
||||
before do
|
||||
instance.order(group: :desc)
|
||||
end
|
||||
|
||||
describe '#results' do
|
||||
it 'is the same as handwriting the query' do
|
||||
expected = PlaceholderUser.merge(PlaceholderUser.joins(:groups).order("groups_users.lastname DESC")).order(id: :desc)
|
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a non existing sortation' do
|
||||
# this is a field protected from sortation
|
||||
before do
|
||||
instance.order(password: :desc)
|
||||
end
|
||||
|
||||
describe '#results' do
|
||||
it 'returns a query not returning anything' do
|
||||
expected = PlaceholderUser.where(Arel::Nodes::Equality.new(1, 0))
|
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql
|
||||
end
|
||||
end
|
||||
|
||||
describe 'valid?' do
|
||||
it 'is false' do
|
||||
expect(instance).to be_invalid
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,100 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe ::PlaceholderUsers::DeleteService, type: :model do
|
||||
skip 'Skipped as we will tackle the DeleteService in a separate PR' do
|
||||
let(:input_user) { FactoryBot.build_stubbed(:user) }
|
||||
let(:project) { FactoryBot.build_stubbed(:project) }
|
||||
|
||||
let(:instance) { described_class.new(input_user, actor) }
|
||||
|
||||
subject { instance.call }
|
||||
|
||||
shared_examples 'deletes the user' do
|
||||
it do
|
||||
expect(input_user).to receive(:lock!)
|
||||
expect(DeleteUserJob).to receive(:perform_later).with(input_user)
|
||||
expect(subject).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'does not delete the user' do
|
||||
it do
|
||||
expect(input_user).not_to receive(:lock!)
|
||||
expect(DeleteUserJob).not_to receive(:perform_later)
|
||||
expect(subject).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
context 'if deletion by admins allowed', with_settings: { users_deletable_by_admins: true } do
|
||||
context 'with admin user' do
|
||||
let(:actor) { FactoryBot.build_stubbed(:admin) }
|
||||
|
||||
it_behaves_like 'deletes the user'
|
||||
end
|
||||
|
||||
context 'with unprivileged system user' do
|
||||
let(:actor) { User.system }
|
||||
|
||||
before do
|
||||
allow(actor).to receive(:admin?).and_return false
|
||||
end
|
||||
|
||||
it_behaves_like 'does not delete the user'
|
||||
end
|
||||
|
||||
context 'with privileged system user' do
|
||||
let(:actor) { User.system }
|
||||
|
||||
it 'performs deletion' do
|
||||
actor.run_given do
|
||||
expect(input_user).to receive(:lock!)
|
||||
expect(DeleteUserJob).to receive(:perform_later).with(input_user)
|
||||
expect(subject).to eq true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'if deletion by admins NOT allowed', with_settings: { users_deletable_by_admins: false } do
|
||||
context 'with admin user' do
|
||||
let(:actor) { FactoryBot.build_stubbed(:admin) }
|
||||
|
||||
it_behaves_like 'does not delete the user'
|
||||
end
|
||||
|
||||
context 'with system user' do
|
||||
let(:actor) { User.system }
|
||||
|
||||
it_behaves_like 'does not delete the user'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'support/pages/page'
|
||||
|
||||
module Pages
|
||||
module Admin
|
||||
module IndividualPrincipals
|
||||
class Edit < ::Pages::Page
|
||||
attr_reader :id
|
||||
attr_reader :individual_principal
|
||||
|
||||
def initialize(individual_principal)
|
||||
@individual_principal = individual_principal
|
||||
@id = individual_principal.id
|
||||
end
|
||||
|
||||
def path
|
||||
"/#{individual_principal.class.name.underscore}s/#{id}/edit"
|
||||
end
|
||||
|
||||
def open_projects_tab!
|
||||
within('.content--tabs') do
|
||||
click_on 'Projects'
|
||||
end
|
||||
end
|
||||
|
||||
def add_to_project!(project_name, as:)
|
||||
open_projects_tab!
|
||||
select_project! project_name
|
||||
Array(as).each { |role| check role }
|
||||
click_on 'Add'
|
||||
|
||||
expect_project(project_name)
|
||||
end
|
||||
|
||||
def remove_from_project!(name)
|
||||
open_projects_tab!
|
||||
find_project(name).find('a[data-method=delete]').click
|
||||
end
|
||||
|
||||
def edit_roles!(membership, roles)
|
||||
find("#member-#{membership.id} .memberships--edit-button").click
|
||||
|
||||
page.within("#member-#{membership.id}-roles-form") do
|
||||
page.all('.form--check-box').each do |f|
|
||||
begin
|
||||
f.set false
|
||||
rescue Selenium::WebDriver::Error::InvalidElementStateError
|
||||
# Happens if an element is disabled
|
||||
end
|
||||
end
|
||||
Array(roles).each { |role| page.check role }
|
||||
page.find('.memberships--edit-submit-button').click
|
||||
end
|
||||
end
|
||||
|
||||
def expect_project(project_name)
|
||||
expect(page).to have_selector('tr', text: project_name, wait: 10)
|
||||
end
|
||||
|
||||
def expect_no_membership(project_name)
|
||||
expect(page).to have_no_selector('tr', text: project_name)
|
||||
end
|
||||
|
||||
def expect_roles(project_name, roles)
|
||||
row = page.find('tr', text: project_name, wait: 10)
|
||||
|
||||
roles.each do |role|
|
||||
expect(row).to have_selector('span', text: role)
|
||||
end
|
||||
end
|
||||
|
||||
def find_project(name)
|
||||
find('tr', text: name)
|
||||
end
|
||||
|
||||
def has_project?(name)
|
||||
has_selector? 'tr', text: name
|
||||
end
|
||||
|
||||
def select_project!(project_name)
|
||||
select(project_name, from: 'membership_project_id')
|
||||
end
|
||||
|
||||
def activate!
|
||||
within '.toolbar-items' do
|
||||
click_button 'Activate'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,89 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'support/pages/page'
|
||||
|
||||
module Pages
|
||||
module Admin
|
||||
module PlaceholderUsers
|
||||
class Index < ::Pages::Page
|
||||
def path
|
||||
"/placeholder_users"
|
||||
end
|
||||
|
||||
def expect_listed(*placeholder_users)
|
||||
rows = page.all 'td.name'
|
||||
expect(rows.map(&:text)).to include(*placeholder_users.map(&:name))
|
||||
end
|
||||
|
||||
def expect_not_listed(*users)
|
||||
rows = page.all 'td.name'
|
||||
expect(rows.map(&:text)).to_not include(*users.map(&:name))
|
||||
end
|
||||
|
||||
def expect_non_listed
|
||||
expect(page)
|
||||
.to have_no_selector('tr.placeholder-user')
|
||||
|
||||
expect(page)
|
||||
.to have_selector('tr.generic-table--empty-row', text: 'There is currently nothing to display.')
|
||||
end
|
||||
|
||||
def filter_by_name(value)
|
||||
fill_in 'Name', with: value
|
||||
click_button 'Apply'
|
||||
end
|
||||
|
||||
def clear_filters
|
||||
click_link 'Clear'
|
||||
end
|
||||
|
||||
def order_by(key)
|
||||
within 'thead' do
|
||||
click_link key
|
||||
end
|
||||
end
|
||||
|
||||
def click_placeholder_user_button(placeholder_user, text)
|
||||
within_user_row(placeholder_user) do
|
||||
click_link text
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def within_placeholder_user_row(placeholder_user)
|
||||
row = find('tr.placeholder_user', text: placeholder_user.name)
|
||||
within row do
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details.
|
||||
#++
|
||||
|
||||
require 'support/pages/page'
|
||||
|
||||
module Pages
|
||||
class NewPlaceholderUser < Page
|
||||
def path
|
||||
'/placeholder_users/new'
|
||||
end
|
||||
|
||||
##
|
||||
# Fills in the given user form fields.
|
||||
def fill_in!(fields = {})
|
||||
form = FormFiller.new fields
|
||||
|
||||
form.fill! 'Name', :name
|
||||
end
|
||||
|
||||
def submit!
|
||||
click_button 'Create'
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user