Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow other plugins to chain alias Project.allowed_to_condition #6

Open
wants to merge 4 commits into
base: redmine-version-2.1-stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
Plugin which allow to setup project permisions to show own time entries to user


## Redmine version
## Redmine version supported

Versions: 2.1-stable, 2.2-stable
2.1-stable and later 2.x releases


## Installation
Expand Down
2 changes: 1 addition & 1 deletion init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
name 'Redmine Own Time Entries plugin'
author '//Twinslash'
description 'Plugin to show users only own time entries in a project'
version '0.0.2'
version '0.0.5'
url 'https://github.com/Belarus2012/SelfSpentTime'
author_url 'http://twinslash.com'

Expand Down
81 changes: 31 additions & 50 deletions lib/redmine_own_time_entries/own_time_entries_project_patch.rb
Original file line number Diff line number Diff line change
@@ -1,65 +1,46 @@
module OwnTimeEntriesProjectPatch

def self.included(base)
base.extend ClassMethods
base.class_eval do
unloadable

# Returns a SQL conditions string used to find all projects for which +user+ has the given +permission+
#
# Valid options:
# * :project => limit the condition to project
# * :with_subprojects => limit the condition to project and its subprojects
# * :member => limit the condition to the user projects
def self.allowed_to_condition(user, permission, options={})
perm = Redmine::AccessControl.permission(permission)
base_statement = (perm && perm.read? ? "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED}" : "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}")
if perm && perm.project_module
# If the permission belongs to a project module, make sure the module is enabled
base_statement << " AND #{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.project_module}')"
end
if options[:project]
project_statement = "#{Project.table_name}.id = #{options[:project].id}"
project_statement << " OR (#{Project.table_name}.lft > #{options[:project].lft} AND #{Project.table_name}.rgt < #{options[:project].rgt})" if options[:with_subprojects]
base_statement = "(#{project_statement}) AND (#{base_statement})"
end
class << self
alias_method_chain :allowed_to_condition, :own_time_entries
end

if user.admin?
base_statement
else
statement_by_role = {}
unless options[:member]
role = user.logged? ? Role.non_member : Role.anonymous
if role.allowed_to?(permission)
statement_by_role[role] = "#{Project.table_name}.is_public = #{connection.quoted_true}"
end
end
if user.logged?
user.projects_by_role.each do |role, projects|
# =========== patch start ===========
if role.allowed_to?(permission) && projects.any?
statement_by_role[role] = "#{Project.table_name}.id IN (#{projects.collect(&:id).join(',')})"
elsif permission == :view_time_entries && role.allowed_to?(:view_only_own_time_entries) && projects.any?
statement_by_role[role] = "#{Project.table_name}.id IN (#{projects.collect(&:id).join(',')}) AND #{TimeEntry.table_name}.user_id = #{user.id}"
end
# =========== patch end ===========
end
end
if statement_by_role.empty?
"1=0"
else
if block_given?
statement_by_role.each do |role, statement|
if s = yield(role, user)
statement_by_role[role] = "(#{statement} AND (#{s}))"
end
end
end
"((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))"
end
end


module ClassMethods
# Returns a SQL conditions string used to find all projects for which +user+ has the given +permission+
#
# Valid options:
# * :project => limit the condition to project
# * :with_subprojects => limit the condition to project and its subprojects
# * :member => limit the condition to the user projects
def allowed_to_condition_with_own_time_entries(user, permission, options={}, &block)
statement = allowed_to_condition_without_own_time_entries(user, permission, options, &block)
project_list = []
if user.logged? and !user.admin? and (permission == :view_time_entries)
user.projects_by_role.each do |role, projects|
if role.allowed_to?(:view_only_own_time_entries) && projects.any?
project_list << projects.collect(&:id)
end
end
end

if project_list.empty?
statement
else
chomp = statement.end_with? "))"
statement = statement.chomp("))") << " OR (#{Project.table_name}.id IN (#{project_list.flatten.uniq.join(',')}) AND (#{TimeEntry.table_name}.user_id = #{user.id}))"
statement += "))" if chomp
statement
end
end

end

end