Refactoring: Replaced home-rolled authorization logic in Controllers with Pundit.

This commit is contained in:
Ryan Lue 2020-03-19 10:39:51 +01:00 committed by Thorsten Eckel
parent 706e51d27b
commit becbdb1baa
153 changed files with 1168 additions and 939 deletions

View file

@ -220,7 +220,7 @@ Naming/MethodParameterName:
Checks for method parameter names that contain capital letters, Checks for method parameter names that contain capital letters,
end in numbers, or do not meet a minimal length. end in numbers, or do not meet a minimal length.
Enabled: true Enabled: true
AllowedNames: e, id, _, ip AllowedNames: e, id, _, ip, to
Lint/BooleanSymbol: Lint/BooleanSymbol:
Description: 'Check for `:true` and `:false` symbols.' Description: 'Check for `:true` and `:false` symbols.'

View file

@ -35,6 +35,9 @@ gem 'argon2'
# core - state machine # core - state machine
gem 'aasm' gem 'aasm'
# core - authorization
gem 'pundit'
# performance - Memcached # performance - Memcached
gem 'dalli' gem 'dalli'
@ -151,6 +154,9 @@ group :development, :test do
gem 'shoulda-matchers' gem 'shoulda-matchers'
gem 'test-unit' gem 'test-unit'
# for testing Pundit authorisation policies in RSpec
gem 'pundit-matchers'
# code coverage # code coverage
gem 'coveralls', require: false gem 'coveralls', require: false
gem 'simplecov' gem 'simplecov'

View file

@ -378,6 +378,10 @@ GEM
pry (>= 0.9.11) pry (>= 0.9.11)
public_suffix (3.0.3) public_suffix (3.0.3)
puma (3.12.4) puma (3.12.4)
pundit (2.0.1)
activesupport (>= 3.0.0)
pundit-matchers (1.6.0)
rspec-rails (>= 3.0.0)
rack (2.2.2) rack (2.2.2)
rack-livereload (0.3.17) rack-livereload (0.3.17)
rack rack
@ -627,6 +631,8 @@ DEPENDENCIES
pry-rescue pry-rescue
pry-stack_explorer pry-stack_explorer
puma (~> 3.12) puma (~> 3.12)
pundit
pundit-matchers
rack-livereload rack-livereload
rails (= 5.2.4.1) rails (= 5.2.4.1)
rails-controller-testing rails-controller-testing

View file

@ -303,7 +303,7 @@ class App.User extends App.Model
Checks if requester has given access level on requested. Checks if requester has given access level on requested.
Possible access levels are: read, update and delete Possible access levels are: read, update and delete
See backend method User#access? See backend policy UserPolicy
requester = App.User.find(1) requester = App.User.find(1)
requested = App.User.find(3) requested = App.User.find(3)

View file

@ -1,47 +0,0 @@
class ApplicationChannelController < ApplicationController
# Extending controllers has to define following constants:
# PERMISSION = "admin.channel_xyz"
# AREA = "XYZ::Account"
def index
render json: channels_data
end
def show
model_show_render(Channel, params)
end
def create
model_create_render(Channel, channel_params)
end
def update
model_update_render(Channel, channel_params)
end
def enable
channel.update!(active: true)
render json: channel
end
def disable
channel.update!(active: false)
render json: channel
end
def destroy
channel.destroy!
render json: {}
end
private
def channel
@channel ||= Channel.lookup(id: params[:id])
end
def channel_params
params.permit!.to_s
end
end

View file

@ -12,5 +12,5 @@ class ApplicationController < ActionController::Base
include ApplicationController::PreventsCsrf include ApplicationController::PreventsCsrf
include ApplicationController::HasSecureContentSecurityPolicyForDownloads include ApplicationController::HasSecureContentSecurityPolicyForDownloads
include ApplicationController::LogsHttpAccess include ApplicationController::LogsHttpAccess
include ApplicationController::ChecksAccess include ApplicationController::Authorizes
end end

View file

@ -4,6 +4,8 @@ module ApplicationController::Authenticates
private private
def permission_check(key) def permission_check(key)
ActiveSupport::Deprecation.warn("Method 'permission_check' is deprecated. Use Pundit policy and `authorize!` instead.")
if @_token_auth if @_token_auth
user = Token.check( user = Token.check(
action: 'api', action: 'api',
@ -76,6 +78,8 @@ module ApplicationController::Authenticates
inactive_user: true, inactive_user: true,
) )
if user && auth_param[:permission] if user && auth_param[:permission]
ActiveSupport::Deprecation.warn("Paramter ':permission' is deprecated. Use Pundit policy and `authorize!` instead.")
user = Token.check( user = Token.check(
action: 'api', action: 'api',
name: token_string, name: token_string,
@ -95,6 +99,8 @@ module ApplicationController::Authenticates
Time.zone.today >= token.expires_at Time.zone.today >= token.expires_at
raise Exceptions::NotAuthorized, 'Not authorized (token expired)!' raise Exceptions::NotAuthorized, 'Not authorized (token expired)!'
end end
@_token = token # remember for Pundit authorization / permit!
end end
@_token_auth = token_string # remember for permission_check @_token_auth = token_string # remember for permission_check
@ -152,7 +158,14 @@ module ApplicationController::Authenticates
def authentication_check_prerequesits(user, auth_type, auth_param) def authentication_check_prerequesits(user, auth_type, auth_param)
raise Exceptions::NotAuthorized, 'Maintenance mode enabled!' if in_maintenance_mode?(user) raise Exceptions::NotAuthorized, 'Maintenance mode enabled!' if in_maintenance_mode?(user)
raise Exceptions::NotAuthorized, 'User is inactive!' if !user.active raise Exceptions::NotAuthorized, 'User is inactive!' if !user.active
raise Exceptions::NotAuthorized, 'Not authorized (user)!' if auth_param[:permission] && !user.permissions?(auth_param[:permission])
if auth_param[:permission]
ActiveSupport::Deprecation.warn("Parameter ':permission' is deprecated. Use Pundit policy and `authorize!` instead.")
if !user.permissions?(auth_param[:permission])
raise Exceptions::NotAuthorized, 'Not authorized (user)!'
end
end
current_user_set(user, auth_type) current_user_set(user, auth_type)
user_device_log(user, auth_type) user_device_log(user, auth_type)

View file

@ -0,0 +1,61 @@
module ApplicationController::Authorizes
extend ActiveSupport::Concern
include Pundit
private
def authorize!(record = policy_record, query = nil)
authorize(record, query)
end
def authorized?(record = policy_record, query = nil)
authorize!(record, query)
true
rescue Exceptions::NotAuthorized, Pundit::NotAuthorizedError
false
end
def policy_record
# check permissions in matching Pundit policy
# Controllers namspace is used (See: https://github.com/varvet/pundit#policy-namespacing)
# [:controllers, self] => Controllers::RolesControllerPolicy
[:controllers, self]
end
# We need a special UserContext when authorizing in controller context
# because of Token authentication which has it's own permissions
# See: https://github.com/varvet/pundit#additional-context
# We use a Delegator here to have transparent / DuckType access
# to the underlying User instance in the Policy
class UserContext < Delegator
def initialize(user, token)
@user = user
@token = token
end
def __getobj__
@user
end
def permissions!(permissions)
raise Exceptions::NotAuthorized, 'authentication failed' if !@user
raise Exceptions::NotAuthorized, 'Not authorized (user)!' if !@user.permissions?(permissions)
return if !@token
return if @token.permissions?(permissions)
raise Exceptions::NotAuthorized, 'Not authorized (token)!'
end
def permissions?(permissions)
permissions!(permissions)
true
rescue Exceptions::NotAuthorized
false
end
end
def pundit_user
@pundit_user ||= UserContext.new(current_user, @_token)
end
end

View file

@ -1,9 +0,0 @@
module ApplicationController::ChecksAccess
extend ActiveSupport::Concern
private
def access!(instance, access)
instance.access!(current_user, access)
end
end

View file

@ -11,6 +11,7 @@ module ApplicationController::HandlesErrors
rescue_from ArgumentError, with: :unprocessable_entity rescue_from ArgumentError, with: :unprocessable_entity
rescue_from Exceptions::UnprocessableEntity, with: :unprocessable_entity rescue_from Exceptions::UnprocessableEntity, with: :unprocessable_entity
rescue_from Exceptions::NotAuthorized, with: :unauthorized rescue_from Exceptions::NotAuthorized, with: :unauthorized
rescue_from Pundit::NotAuthorizedError, with: :pundit_not_authorized_error
end end
def not_found(e) def not_found(e)
@ -32,12 +33,22 @@ module ApplicationController::HandlesErrors
end end
def unauthorized(e) def unauthorized(e)
logger.info { e }
error = humanize_error(e) error = humanize_error(e)
response.headers['X-Failure'] = error.fetch(:error_human, error[:error]) response.headers['X-Failure'] = error.fetch(:error_human, error[:error])
respond_to_exception(e, :unauthorized) respond_to_exception(e, :unauthorized)
http_log http_log
end end
def pundit_not_authorized_error(e)
logger.info { e }
# check if a special authorization_error should be shown in the result payload
# which was raised in one of the policies. Fall back to a simple "Not authorized"
# error to hide actual cause for security reasons.
exeption = e.policy.custom_exception || Exceptions::NotAuthorized.new
unauthorized(exeption)
end
private private
def respond_to_exception(e, status) def respond_to_exception(e, status)

View file

@ -95,10 +95,4 @@ module ApplicationController::HasUser
session[:user_agent] = request.env['HTTP_USER_AGENT'] session[:user_agent] = request.env['HTTP_USER_AGENT']
end end
def valid_session_with_user
return true if current_user
raise Exceptions::UnprocessableEntity, 'No session user!'
end
end end

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ApplicationsController < ApplicationController class ApplicationsController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.api') } prepend_before_action { authentication_check && authorize! }
def index def index
all = Doorkeeper::Application.all all = Doorkeeper::Application.all

View file

@ -1,6 +1,6 @@
# Copyright (C) 2012-2015 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2015 Zammad Foundation, http://zammad-foundation.org/
class CalendarSubscriptionsController < ApplicationController class CalendarSubscriptionsController < ApplicationController
prepend_before_action { authentication_check( { basic_auth_promt: true, permission: 'user_preferences.calendar' } ) } prepend_before_action { authentication_check(basic_auth_promt: true) && authorize! }
# @path [GET] /calendar_subscriptions # @path [GET] /calendar_subscriptions
# #

View file

@ -1,8 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class CalendarsController < ApplicationController class CalendarsController < ApplicationController
prepend_before_action -> { authentication_check(permission: 'admin.calendar') }, only: %i[init index show create update destroy] prepend_before_action { authentication_check && authorize! }
prepend_before_action -> { authentication_check(permission: 'admin') }, only: %i[timezones]
def init def init
assets = {} assets = {}

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ChannelsEmailController < ApplicationController class ChannelsEmailController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.channel_email') } prepend_before_action { authentication_check && authorize! }
def index def index
system_online_service = Setting.get('system_online_service') system_online_service = Setting.get('system_online_service')

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ChannelsFacebookController < ApplicationController class ChannelsFacebookController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.channel_facebook') } prepend_before_action { authentication_check && authorize! }
def index def index
assets = {} assets = {}

View file

@ -1,8 +1,5 @@
class ChannelsSmsController < ApplicationChannelController class ChannelsSmsController < ApplicationController
PERMISSION = 'admin.channel_sms'.freeze prepend_before_action -> { authentication_check && authorize! }, except: [:webhook]
AREA = ['Sms::Notification'.freeze, 'Sms::Account'.freeze].freeze
prepend_before_action -> { authentication_check(permission: self.class::PERMISSION) }, except: [:webhook]
skip_before_action :verify_csrf_token, only: [:webhook] skip_before_action :verify_csrf_token, only: [:webhook]
def index def index
@ -15,6 +12,33 @@ class ChannelsSmsController < ApplicationChannelController
} }
end end
def show
model_show_render(Channel, params)
end
def create
model_create_render(Channel, channel_params)
end
def update
model_update_render(Channel, channel_params)
end
def enable
channel.update!(active: true)
render json: channel
end
def disable
channel.update!(active: false)
render json: channel
end
def destroy
channel.destroy!
render json: {}
end
def test def test
raise 'Missing parameter options.adapter' if params[:options][:adapter].blank? raise 'Missing parameter options.adapter' if params[:options][:adapter].blank?
@ -49,13 +73,17 @@ class ChannelsSmsController < ApplicationChannelController
private private
def channel
@channel ||= Channel.lookup(id: params[:id])
end
def test_options def test_options
params.permit(:recipient, :message) params.permit(:recipient, :message)
end end
def channel_params def channel_params
raise 'Missing area params' if params[:area].blank? raise 'Missing area params' if params[:area].blank?
if !self.class::AREA.include?(params[:area]) if ['Sms::Notification', 'Sms::Account'].exclude?(params[:area])
raise "Invalid area '#{params[:area]}'!" raise "Invalid area '#{params[:area]}'!"
end end
raise 'Missing options params' if params[:options].blank? raise 'Missing options params' if params[:options].blank?

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ChannelsTelegramController < ApplicationController class ChannelsTelegramController < ApplicationController
prepend_before_action -> { authentication_check(permission: 'admin.channel_telegram') }, except: [:webhook] prepend_before_action -> { authentication_check && authorize! }, except: [:webhook]
skip_before_action :verify_csrf_token, only: [:webhook] skip_before_action :verify_csrf_token, only: [:webhook]
def index def index

View file

@ -2,7 +2,7 @@
require_dependency 'channel/driver/twitter' require_dependency 'channel/driver/twitter'
class ChannelsTwitterController < ApplicationController class ChannelsTwitterController < ApplicationController
prepend_before_action -> { authentication_check(permission: 'admin.channel_twitter') }, except: %i[webhook_incoming webhook_verify] prepend_before_action -> { authentication_check && authorize! }, except: %i[webhook_incoming webhook_verify]
skip_before_action :verify_csrf_token, only: %i[webhook_incoming webhook_verify] skip_before_action :verify_csrf_token, only: %i[webhook_incoming webhook_verify]
before_action :validate_webhook_signature!, only: :webhook_incoming before_action :validate_webhook_signature!, only: :webhook_incoming

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ChatSessionsController < ApplicationController class ChatSessionsController < ApplicationController
prepend_before_action { authentication_check(permission: 'chat.agent') } prepend_before_action { authentication_check && authorize! }
def show def show
model_show_render(Chat::Session, params) model_show_render(Chat::Session, params)

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ChatsController < ApplicationController class ChatsController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.channel_chat') } prepend_before_action { authentication_check && authorize! }
def index def index
chat_ids = [] chat_ids = []

View file

@ -4,12 +4,11 @@ module ChecksUserAttributesByCurrentUserPermission
private private
def check_attributes_by_current_user_permission(params) def check_attributes_by_current_user_permission(params)
authorize!
# admins can do whatever they want # admins can do whatever they want
return true if current_user.permissions?('admin.user') return true if current_user.permissions?('admin.user')
# non-agents (customers) can't set anything
raise Exceptions::NotAuthorized if !current_user.permissions?('ticket.agent')
# regular agents are not allowed to set Groups and Roles # regular agents are not allowed to set Groups and Roles
%w[Role Group].each do |model| %w[Role Group].each do |model|

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class CtiController < ApplicationController class CtiController < ApplicationController
prepend_before_action { authentication_check(permission: 'cti.agent') } prepend_before_action { authentication_check && authorize! }
# list current caller log # list current caller log
# GET /api/v1/cti/log # GET /api/v1/cti/log

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class EmailAddressesController < ApplicationController class EmailAddressesController < ApplicationController
prepend_before_action :authentication_check prepend_before_action { authentication_check && authorize! }
=begin =begin
@ -46,7 +46,6 @@ curl http://localhost/api/v1/email_addresses.json -v -u #{login}:#{password}
=end =end
def index def index
permission_check(['admin.channel_email', 'ticket.agent'])
model_index_render(EmailAddress, params) model_index_render(EmailAddress, params)
end end
@ -68,7 +67,6 @@ curl http://localhost/api/v1/email_addresses/#{id}.json -v -u #{login}:#{passwor
=end =end
def show def show
permission_check(['admin.channel_email', 'ticket.agent'])
model_show_render(EmailAddress, params) model_show_render(EmailAddress, params)
end end
@ -99,7 +97,6 @@ curl http://localhost/api/v1/email_addresses.json -v -u #{login}:#{password} -H
=end =end
def create def create
permission_check('admin.channel_email')
model_create_render(EmailAddress, params) model_create_render(EmailAddress, params)
end end
@ -130,7 +127,6 @@ curl http://localhost/api/v1/email_addresses/#{id}.json -v -u #{login}:#{passwor
=end =end
def update def update
permission_check('admin.channel_email')
model_update_render(EmailAddress, params) model_update_render(EmailAddress, params)
end end
@ -148,7 +144,6 @@ curl http://localhost/api/v1/email_addresses/#{id}.json -v -u #{login}:#{passwor
=end =end
def destroy def destroy
permission_check('admin.channel_email')
model_destroy_render(EmailAddress, params) model_destroy_render(EmailAddress, params)
end end
end end

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ExternalCredentialsController < ApplicationController class ExternalCredentialsController < ApplicationController
prepend_before_action :permission_check prepend_before_action { authentication_check && authorize! }
def index def index
model_index_render(ExternalCredential, params) model_index_render(ExternalCredential, params)
@ -53,29 +53,4 @@ class ExternalCredentialsController < ApplicationController
def app_url(provider, channel_id) def app_url(provider, channel_id)
ExternalCredential.app_url(provider, channel_id) ExternalCredential.app_url(provider, channel_id)
end end
def permission_check
if params[:id].present? && ExternalCredential.exists?(params[:id])
external_credential = ExternalCredential.find(params[:id])
raise 'No such ExternalCredential!' if !external_credential
authentication_check(permission: ["admin.channel_#{external_credential.name}"])
return
end
if params[:name].present? || params[:provider].present?
if params[:name].present?
name = params[:name].downcase
elsif params[:provider].present?
name = params[:provider].downcase
else
raise 'Missing name/provider!'
end
authentication_check(permission: ["admin.channel_#{name}"])
return
end
authentication_check(permission: ['admin'])
end
end end

View file

@ -3,9 +3,9 @@
class FirstStepsController < ApplicationController class FirstStepsController < ApplicationController
prepend_before_action :authentication_check prepend_before_action :authentication_check
def index before_action -> { render json: [] }, if: -> { !authorized? }
return if !access?
def index
invite_agents = false invite_agents = false
#if User.of_role('Agent').count > 2 #if User.of_role('Agent').count > 2
# invite_agents = true # invite_agents = true
@ -169,8 +169,6 @@ class FirstStepsController < ApplicationController
end end
def test_ticket def test_ticket
return if !access?
agent = current_user agent = current_user
customer = test_customer customer = test_customer
from = "#{customer.fullname} <#{customer.email}>" from = "#{customer.fullname} <#{customer.email}>"
@ -221,13 +219,6 @@ class FirstStepsController < ApplicationController
User.find_by(login: 'nicole.braun@zammad.org') User.find_by(login: 'nicole.braun@zammad.org')
end end
def access?
return true if current_user.permissions?(['admin', 'ticket.agent'])
render json: []
false
end
def check_availability(result) def check_availability(result)
test_ticket_active = true test_ticket_active = true
overview = test_overview overview = test_overview

View file

@ -1,13 +1,14 @@
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
class FormController < ApplicationController class FormController < ApplicationController
prepend_before_action -> { authorize! }, only: %i[configuration submit]
skip_before_action :verify_csrf_token skip_before_action :verify_csrf_token
before_action :cors_preflight_check before_action :cors_preflight_check
after_action :set_access_control_headers_execute after_action :set_access_control_headers_execute
skip_before_action :user_device_check skip_before_action :user_device_check
def configuration def configuration
return if !enabled?
return if !fingerprint_exists? return if !fingerprint_exists?
return if limit_reached? return if limit_reached?
@ -23,7 +24,7 @@ class FormController < ApplicationController
token: token_gen(params[:fingerprint]) token: token_gen(params[:fingerprint])
} }
if params[:test] && current_user && current_user.permissions?('admin.channel_formular') if authorized?(policy_record, :test?)
result[:enabled] = true result[:enabled] = true
end end
@ -31,7 +32,6 @@ class FormController < ApplicationController
end end
def submit def submit
return if !enabled?
return if !fingerprint_exists? return if !fingerprint_exists?
return if !token_valid?(params[:token], params[:fingerprint]) return if !token_valid?(params[:token], params[:fingerprint])
return if limit_reached? return if limit_reached?
@ -144,6 +144,14 @@ class FormController < ApplicationController
private private
# we don't wann to tell what the cause for the authorization error is
# so we capture the exception and raise an anonymized one
def authorize!(*)
super
rescue Pundit::NotAuthorizedError
raise Exceptions::NotAuthorized
end
def token_gen(fingerprint) def token_gen(fingerprint)
crypt = ActiveSupport::MessageEncryptor.new(Setting.get('application_secret')[0, 32]) crypt = ActiveSupport::MessageEncryptor.new(Setting.get('application_secret')[0, 32])
fingerprint = "#{Base64.strict_encode64(Setting.get('fqdn'))}:#{Time.zone.now.to_i}:#{Base64.strict_encode64(fingerprint)}" fingerprint = "#{Base64.strict_encode64(Setting.get('fqdn'))}:#{Time.zone.now.to_i}:#{Base64.strict_encode64(fingerprint)}"
@ -216,12 +224,4 @@ class FormController < ApplicationController
Rails.logger.info 'No fingerprint given!' Rails.logger.info 'No fingerprint given!'
raise Exceptions::NotAuthorized raise Exceptions::NotAuthorized
end end
def enabled?
return true if params[:test] && current_user && current_user.permissions?('admin.channel_formular')
return true if Setting.get('form_ticket_create')
raise Exceptions::NotAuthorized
end
end end

View file

@ -1,5 +1,6 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class GettingStartedController < ApplicationController class GettingStartedController < ApplicationController
prepend_before_action -> { authorize! }, only: [:base]
=begin =begin
@ -105,10 +106,6 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
end end
def base def base
# check admin permissions
permission_check('admin.wizard')
# validate url # validate url
messages = {} messages = {}
settings = {} settings = {}

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class GroupsController < ApplicationController class GroupsController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.group') } prepend_before_action { authentication_check && authorize! }
=begin =begin

View file

@ -1,11 +1,10 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class HttpLogsController < ApplicationController class HttpLogsController < ApplicationController
prepend_before_action :authentication_check prepend_before_action { authentication_check && authorize! }
# GET /http_logs/:facility # GET /http_logs/:facility
def index def index
permission_check('admin.*')
list = if params[:facility] list = if params[:facility]
HttpLog.where(facility: params[:facility]).order(created_at: :desc).limit(params[:limit] || 50) HttpLog.where(facility: params[:facility]).order(created_at: :desc).limit(params[:limit] || 50)
else else
@ -16,7 +15,6 @@ class HttpLogsController < ApplicationController
# POST /http_logs # POST /http_logs
def create def create
permission_check('admin.*')
model_create_render(HttpLog, params) model_create_render(HttpLog, params)
end end

View file

@ -3,7 +3,7 @@
class Integration::ExchangeController < ApplicationController class Integration::ExchangeController < ApplicationController
include Integration::ImportJobBase include Integration::ImportJobBase
prepend_before_action { authentication_check(permission: 'admin.integration.exchange') } prepend_before_action { authentication_check && authorize! }
def autodiscover def autodiscover
answer_with do answer_with do

View file

@ -1,9 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class Integration::IdoitController < ApplicationController class Integration::IdoitController < ApplicationController
prepend_before_action -> { authentication_check(permission: ['agent.integration.idoit', 'admin.integration.idoit']) }, except: %i[verify query update] prepend_before_action { authentication_check && authorize! }
prepend_before_action -> { authentication_check(permission: ['admin.integration.idoit']) }, only: [:verify]
prepend_before_action -> { authentication_check(permission: ['ticket.agent']) }, only: %i[query update]
def verify def verify
response = ::Idoit.verify(params[:api_token], params[:endpoint], params[:client_id]) response = ::Idoit.verify(params[:api_token], params[:endpoint], params[:client_id])
@ -39,7 +37,7 @@ class Integration::IdoitController < ApplicationController
params[:object_ids] ||= [] params[:object_ids] ||= []
ticket = Ticket.find(params[:ticket_id]) ticket = Ticket.find(params[:ticket_id])
ticket.with_lock do ticket.with_lock do
access!(ticket, 'read') authorize!(ticket, :show?)
ticket.preferences[:idoit] ||= {} ticket.preferences[:idoit] ||= {}
ticket.preferences[:idoit][:object_ids] = Array(params[:object_ids]).uniq ticket.preferences[:idoit][:object_ids] = Array(params[:object_ids]).uniq
ticket.save! ticket.save!

View file

@ -6,7 +6,7 @@ require_dependency 'ldap/group'
class Integration::LdapController < ApplicationController class Integration::LdapController < ApplicationController
include Integration::ImportJobBase include Integration::ImportJobBase
prepend_before_action { authentication_check(permission: 'admin.integration.ldap') } prepend_before_action { authentication_check && authorize! }
def discover def discover
answer_with do answer_with do

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class JobsController < ApplicationController class JobsController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.scheduler') } prepend_before_action { authentication_check && authorize! }
def index def index
model_index_render(Job, params) model_index_render(Job, params)

View file

@ -2,7 +2,7 @@
class KnowledgeBase::Answer::AttachmentsController < ApplicationController class KnowledgeBase::Answer::AttachmentsController < ApplicationController
prepend_before_action :authentication_check prepend_before_action :authentication_check
prepend_before_action { permission_check('knowledge_base.editor') } prepend_before_action :authorize!
before_action :fetch_answer before_action :fetch_answer

View file

@ -3,8 +3,6 @@
class KnowledgeBase::AnswersController < KnowledgeBase::BaseController class KnowledgeBase::AnswersController < KnowledgeBase::BaseController
include HasPublishing include HasPublishing
before_action :check_reader_access, only: :show
# accessible outside of specific Knowledge Base # accessible outside of specific Knowledge Base
# /api/v1/knowledge_bases/recent_answers # /api/v1/knowledge_bases/recent_answers
def recent_answers def recent_answers
@ -83,15 +81,4 @@ class KnowledgeBase::AnswersController < KnowledgeBase::BaseController
render json: { id: object.id, assets: assets }, status: :created render json: { id: object.id, assets: assets }, status: :created
end end
private
def check_reader_access
return if current_user.permissions? 'knowledge_base.editor'
object = klass.find params[:id]
return if object.can_be_published_aasm.internal? || object.can_be_published_aasm.published?
raise ActiveRecord::RecordNotFound
end
end end

View file

@ -2,8 +2,7 @@
class KnowledgeBase::BaseController < ApplicationController class KnowledgeBase::BaseController < ApplicationController
prepend_before_action :authentication_check prepend_before_action :authentication_check
before_action :ensure_editor_or_reader before_action :authorize!
before_action :ensure_editor, only: %i[create update destroy]
def show def show
model_show_render(klass, params_for_permission) model_show_render(klass, params_for_permission)
@ -21,21 +20,13 @@ class KnowledgeBase::BaseController < ApplicationController
model_destroy_render(klass, params_for_permission) model_destroy_render(klass, params_for_permission)
end end
private
def klass def klass
@klass ||= controller_path.classify.constantize @klass ||= controller_path.classify.constantize
end end
private
def params_for_permission def params_for_permission
params.permit klass.agent_allowed_params params.permit klass.agent_allowed_params
end end
def ensure_editor
permission_check 'knowledge_base.editor'
end
def ensure_editor_or_reader
permission_check 'knowledge_base.*'
end
end end

View file

@ -2,7 +2,6 @@
class KnowledgeBase::CategoriesController < KnowledgeBase::BaseController class KnowledgeBase::CategoriesController < KnowledgeBase::BaseController
before_action :load_knowledge_base, only: %i[reorder_root_categories reorder_categories reorder_answers] before_action :load_knowledge_base, only: %i[reorder_root_categories reorder_categories reorder_answers]
before_action :check_reader_access, only: :show # rubocop:disable Rails/LexicallyScopedActionFilter
def reorder_root_categories def reorder_root_categories
reorder @knowledge_base.categories.root, params[:ordered_ids], KnowledgeBase::Category reorder @knowledge_base.categories.root, params[:ordered_ids], KnowledgeBase::Category
@ -46,14 +45,4 @@ class KnowledgeBase::CategoriesController < KnowledgeBase::BaseController
@knowledge_base = KnowledgeBase.find params[:knowledge_base_id] @knowledge_base = KnowledgeBase.find params[:knowledge_base_id]
@category = @knowledge_base.categories.find params[:id] if params.key? :id @category = @knowledge_base.categories.find params[:id] if params.key? :id
end end
def check_reader_access
return if current_user.permissions? 'knowledge_base.editor'
object = klass.find params[:id]
return if object.internal_content?
raise ActiveRecord::RecordNotFound
end
end end

View file

@ -1,9 +1,5 @@
# Copyright (C) 2012-2017 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2017 Zammad Foundation, http://zammad-foundation.org/
class KnowledgeBase::ManageController < KnowledgeBase::BaseController class KnowledgeBase::ManageController < KnowledgeBase::BaseController
prepend_before_action { permission_check('admin.knowledge_base') }
skip_before_action :ensure_editor_or_reader
skip_before_action :ensure_editor
def init def init
render json: assets render json: assets
end end

View file

@ -1,20 +1,10 @@
# Copyright (C) 2012-2017 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2017 Zammad Foundation, http://zammad-foundation.org/
class KnowledgeBasesController < KnowledgeBase::BaseController class KnowledgeBasesController < KnowledgeBase::BaseController
skip_before_action :ensure_editor_or_reader, only: :init
def init def init
render json: assets(params[:answer_translation_content_ids]) render json: assets(params[:answer_translation_content_ids])
end end
def create
raise Exceptions::NotAuthorized
end
def destroy
raise Exceptions::NotAuthorized
end
private private
def assets(answer_translation_content_ids = nil) def assets(answer_translation_content_ids = nil)

View file

@ -1,7 +1,10 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class MonitoringController < ApplicationController class MonitoringController < ApplicationController
prepend_before_action -> { authentication_check(permission: 'admin.monitoring') }, except: %i[health_check status amount_check] prepend_before_action { authorize! }
prepend_before_action -> { authentication_check }, except: %i[health_check status amount_check]
prepend_before_action -> { authentication_check_only }, only: %i[health_check status amount_check]
skip_before_action :verify_csrf_token skip_before_action :verify_csrf_token
=begin =begin
@ -27,8 +30,6 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
=end =end
def health_check def health_check
token_or_permission_check
issues = [] issues = []
actions = Set.new actions = Set.new
@ -210,8 +211,6 @@ curl http://localhost/api/v1/monitoring/status?token=XXX
=end =end
def status def status
token_or_permission_check
last_login = nil last_login = nil
last_login_user = User.where('last_login IS NOT NULL').order(last_login: :desc).limit(1).first last_login_user = User.where('last_login IS NOT NULL').order(last_login: :desc).limit(1).first
if last_login_user if last_login_user
@ -298,8 +297,6 @@ curl http://localhost/api/v1/monitoring/amount_check?token=XXX&periode=1h
=end =end
def amount_check def amount_check
token_or_permission_check
raise Exceptions::UnprocessableEntity, 'periode is missing!' if params[:periode].blank? raise Exceptions::UnprocessableEntity, 'periode is missing!' if params[:periode].blank?
scale = params[:periode][-1, 1] scale = params[:periode][-1, 1]
@ -370,7 +367,6 @@ curl http://localhost/api/v1/monitoring/amount_check?token=XXX&periode=1h
end end
def token def token
access_check
token = SecureRandom.urlsafe_base64(40) token = SecureRandom.urlsafe_base64(40)
Setting.set('monitoring_token', token) Setting.set('monitoring_token', token)
@ -381,27 +377,8 @@ curl http://localhost/api/v1/monitoring/amount_check?token=XXX&periode=1h
end end
def restart_failed_jobs def restart_failed_jobs
access_check
Scheduler.restart_failed_jobs Scheduler.restart_failed_jobs
render json: {}, status: :ok render json: {}, status: :ok
end end
private
def token_or_permission_check
user = authentication_check_only(permission: 'admin.monitoring')
return if user
return if Setting.get('monitoring_token') == params[:token]
raise Exceptions::NotAuthorized
end
def access_check
return if Permission.find_by(name: 'admin.monitoring', active: true)
raise Exceptions::NotAuthorized
end
end end

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ObjectManagerAttributesController < ApplicationController class ObjectManagerAttributesController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.object') } prepend_before_action { authentication_check && authorize! }
# GET /object_manager_attributes_list # GET /object_manager_attributes_list
def list def list

View file

@ -1,6 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class OnlineNotificationsController < ApplicationController class OnlineNotificationsController < ApplicationController
prepend_before_action -> { authorize! }, only: %i[show update destroy]
prepend_before_action :authentication_check prepend_before_action :authentication_check
=begin =begin
@ -102,8 +103,6 @@ curl http://localhost/api/v1/online_notifications/#{id} -v -u #{login}:#{passwor
=end =end
def show def show
return if !access?
model_show_render(OnlineNotification, params) model_show_render(OnlineNotification, params)
end end
@ -131,8 +130,6 @@ curl http://localhost/api/v1/online_notifications -v -u #{login}:#{password} -H
=end =end
def update def update
return if !access?
model_update_render(OnlineNotification, params) model_update_render(OnlineNotification, params)
end end
@ -150,8 +147,6 @@ curl http://localhost/api/v1/online_notifications/{id}.json -v -u #{login}:#{pas
=end =end
def destroy def destroy
return if !access?
model_destroy_render(OnlineNotification, params) model_destroy_render(OnlineNotification, params)
end end
@ -180,14 +175,4 @@ curl http://localhost/api/v1/online_notifications/mark_all_as_read -v -u #{login
end end
render json: {}, status: :ok render json: {}, status: :ok
end end
private
def access?
notification = OnlineNotification.find(params[:id])
return true if notification.user_id == current_user.id
raise Exceptions::NotAuthorized
end
end end

View file

@ -1,7 +1,8 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class OrganizationsController < ApplicationController class OrganizationsController < ApplicationController
prepend_before_action :authentication_check prepend_before_action -> { authorize! }, except: %i[index show]
prepend_before_action { authentication_check }
=begin =begin
@ -59,15 +60,7 @@ curl http://localhost/api/v1/organizations -v -u #{login}:#{password}
per_page = 500 per_page = 500
end end
# only allow customer to fetch his own organization organizations = policy_scope(Organization).order(id: :asc).offset(offset).limit(per_page)
organizations = []
if !current_user.permissions?(['admin.organization', 'ticket.agent'])
if current_user.organization_id
organizations = Organization.where(id: current_user.organization_id).order(id: :asc).offset(offset).limit(per_page)
end
else
organizations = Organization.all.order(id: :asc).offset(offset).limit(per_page)
end
if response_expand? if response_expand?
list = [] list = []
@ -117,14 +110,17 @@ curl http://localhost/api/v1/organizations/#{id} -v -u #{login}:#{password}
=end =end
def show def show
begin
authorize!
rescue Pundit::NotAuthorizedError
# we have a special case here where Users that have no
# organization can request any organization_id but get
# an empty response. However, users with an organization_id
# get that error
raise if current_user.organization_id
# only allow customer to fetch his own organization render json: {}
if !current_user.permissions?(['admin.organization', 'ticket.agent']) return
if !current_user.organization_id
render json: {}
return
end
raise Exceptions::NotAuthorized if params[:id].to_i != current_user.organization_id
end end
if response_expand? if response_expand?
@ -168,7 +164,6 @@ curl http://localhost/api/v1/organizations -v -u #{login}:#{password} -H "Conten
=end =end
def create def create
permission_check(['admin.organization', 'ticket.agent'])
model_create_render(Organization, params) model_create_render(Organization, params)
end end
@ -199,7 +194,6 @@ curl http://localhost/api/v1/organizations -v -u #{login}:#{password} -H "Conten
=end =end
def update def update
permission_check(['admin.organization', 'ticket.agent'])
model_update_render(Organization, params) model_update_render(Organization, params)
end end
@ -217,15 +211,12 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co
=end =end
def destroy def destroy
permission_check(['admin.organization', 'ticket.agent'])
model_references_check(Organization, params) model_references_check(Organization, params)
model_destroy_render(Organization, params) model_destroy_render(Organization, params)
end end
# GET /api/v1/organizations/search # GET /api/v1/organizations/search
def search def search
raise Exceptions::NotAuthorized if !current_user.permissions?(['admin.organization', 'ticket.agent'])
per_page = params[:per_page] || params[:limit] || 100 per_page = params[:per_page] || params[:limit] || 100
per_page = per_page.to_i per_page = per_page.to_i
if per_page > 500 if per_page > 500
@ -301,8 +292,6 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co
# GET /api/v1/organizations/history/1 # GET /api/v1/organizations/history/1
def history def history
raise Exceptions::NotAuthorized if !current_user.permissions?(['admin.organization', 'ticket.agent'])
# get organization data # get organization data
organization = Organization.find(params[:id]) organization = Organization.find(params[:id])
@ -319,7 +308,6 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co
# @response_message 200 File download. # @response_message 200 File download.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_example def import_example
permission_check('admin.organization')
send_data( send_data(
Organization.csv_example, Organization.csv_example,
filename: 'organization-example.csv', filename: 'organization-example.csv',
@ -338,7 +326,6 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co
# @response_message 201 Import started. # @response_message 201 Import started.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_start def import_start
permission_check('admin.user')
string = params[:data] string = params[:data]
if string.blank? && params[:file].present? if string.blank? && params[:file].present?
string = params[:file].read.force_encoding('utf-8') string = params[:file].read.force_encoding('utf-8')

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class OverviewsController < ApplicationController class OverviewsController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.overview') } prepend_before_action { authentication_check && authorize! }
=begin =begin

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class PackagesController < ApplicationController class PackagesController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.package') } prepend_before_action { authentication_check && authorize! }
# GET /api/v1/packages # GET /api/v1/packages
def index def index

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class PostmasterFiltersController < ApplicationController class PostmasterFiltersController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.channel_email') } prepend_before_action { authentication_check && authorize! }
=begin =begin

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ProxyController < ApplicationController class ProxyController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.system') } prepend_before_action { authentication_check && authorize! }
# POST /api/v1/proxy # POST /api/v1/proxy
def test def test

View file

@ -1,5 +1,5 @@
class ReportProfilesController < ApplicationController class ReportProfilesController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.report_profile') } prepend_before_action { authentication_check && authorize! }
=begin =begin

View file

@ -1,6 +1,6 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ReportsController < ApplicationController class ReportsController < ApplicationController
prepend_before_action { authentication_check(permission: 'report') } prepend_before_action { authentication_check && authorize! }
# GET /api/reports/config # GET /api/reports/config
def reporting_config def reporting_config

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class RolesController < ApplicationController class RolesController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.role') } prepend_before_action { authentication_check && authorize! }
=begin =begin

View file

@ -7,10 +7,6 @@ class SearchController < ApplicationController
# GET|POST /api/v1/search/:objects # GET|POST /api/v1/search/:objects
def search_generic def search_generic
# enable search only for users with valid session
raise Exceptions::NotAuthorized if !current_user
# get params # get params
query = params[:query] query = params[:query]
if query.respond_to?(:permit!) if query.respond_to?(:permit!)

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class SessionsController < ApplicationController class SessionsController < ApplicationController
prepend_before_action :authentication_check, only: %i[switch_to_user list delete] prepend_before_action -> { authentication_check && authorize! }, only: %i[switch_to_user list delete]
skip_before_action :verify_csrf_token, only: %i[show destroy create_omniauth failure_omniauth] skip_before_action :verify_csrf_token, only: %i[show destroy create_omniauth failure_omniauth]
skip_before_action :user_device_check, only: %i[create_sso] skip_before_action :user_device_check, only: %i[create_sso]
@ -97,8 +97,6 @@ class SessionsController < ApplicationController
# "switch" to user # "switch" to user
def switch_to_user def switch_to_user
permission_check(['admin.session', 'admin.user'])
# check user # check user
if !params[:id] if !params[:id]
render( render(
@ -176,7 +174,6 @@ class SessionsController < ApplicationController
end end
def list def list
permission_check('admin.session')
assets = {} assets = {}
sessions_clean = [] sessions_clean = []
SessionHelper.list.each do |session| SessionHelper.list.each do |session|
@ -197,7 +194,6 @@ class SessionsController < ApplicationController
end end
def delete def delete
permission_check('admin.session')
SessionHelper.destroy(params[:id]) SessionHelper.destroy(params[:id])
render json: {} render json: {}
end end

View file

@ -1,13 +1,13 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class SettingsController < ApplicationController class SettingsController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.*') } prepend_before_action { authentication_check && authorize! }
# GET /settings # GET /settings
def index def index
list = [] list = []
Setting.all.each do |setting| Setting.all.each do |setting|
next if setting.preferences[:permission] && !current_user.permissions?(setting.preferences[:permission]) next if !authorized?(setting, :show?)
list.push setting list.push setting
end end
@ -16,7 +16,6 @@ class SettingsController < ApplicationController
# GET /settings/1 # GET /settings/1
def show def show
check_access('read')
model_show_render(Setting, params) model_show_render(Setting, params)
end end
@ -27,14 +26,12 @@ class SettingsController < ApplicationController
# PUT /settings/1 # PUT /settings/1
def update def update
check_access('write')
clean_params = keep_certain_attributes clean_params = keep_certain_attributes
model_update_render(Setting, clean_params) model_update_render(Setting, clean_params)
end end
# PUT /settings/image/:id # PUT /settings/image/:id
def update_image def update_image
check_access('write')
clean_params = keep_certain_attributes clean_params = keep_certain_attributes
if !clean_params[:logo] if !clean_params[:logo]
@ -105,20 +102,4 @@ class SettingsController < ApplicationController
end end
params params
end end
def check_access(type)
setting = Setting.lookup(id: params[:id])
if setting.preferences[:permission] && !current_user.permissions?(setting.preferences[:permission])
raise Exceptions::NotAuthorized, "Not authorized (required #{setting.preferences[:permission].inspect})"
end
if type == 'write'
return true if !Setting.get('system_online_service')
if setting.preferences && setting.preferences[:online_service_disable]
raise Exceptions::NotAuthorized, 'Not authorized (service disabled)'
end
end
true
end
end end

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class SignaturesController < ApplicationController class SignaturesController < ApplicationController
prepend_before_action :authentication_check prepend_before_action { authentication_check && authorize! }
=begin =begin
@ -47,7 +47,6 @@ curl http://localhost/api/v1/signatures.json -v -u #{login}:#{password}
=end =end
def index def index
permission_check(['admin.channel_email', 'ticket.agent'])
model_index_render(Signature, params) model_index_render(Signature, params)
end end
@ -69,7 +68,6 @@ curl http://localhost/api/v1/signatures/#{id}.json -v -u #{login}:#{password}
=end =end
def show def show
permission_check(['admin.channel_email', 'ticket.agent'])
model_show_render(Signature, params) model_show_render(Signature, params)
end end
@ -98,7 +96,6 @@ curl http://localhost/api/v1/signatures.json -v -u #{login}:#{password} -H "Cont
=end =end
def create def create
permission_check(['admin.channel_email'])
model_create_render(Signature, params) model_create_render(Signature, params)
end end
@ -127,7 +124,6 @@ curl http://localhost/api/v1/signatures.json -v -u #{login}:#{password} -H "Cont
=end =end
def update def update
permission_check(['admin.channel_email'])
model_update_render(Signature, params) model_update_render(Signature, params)
end end
@ -142,7 +138,6 @@ Test:
=end =end
def destroy def destroy
permission_check(['admin.channel_email'])
model_destroy_render(Signature, params) model_destroy_render(Signature, params)
end end
end end

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class SlasController < ApplicationController class SlasController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.sla') } prepend_before_action { authentication_check && authorize! }
=begin =begin

View file

@ -1,7 +1,8 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TagsController < ApplicationController class TagsController < ApplicationController
prepend_before_action :authentication_check prepend_before_action -> { authorize! }, only: %i[admin_list admin_create admin_rename admin_delete]
prepend_before_action { authentication_check }
# GET /api/v1/tag_search?term=abc # GET /api/v1/tag_search?term=abc
def search def search
@ -60,7 +61,6 @@ class TagsController < ApplicationController
# GET /api/v1/tag_list # GET /api/v1/tag_list
def admin_list def admin_list
permission_check('admin.tag')
list = Tag::Item.order(name: :asc).limit(params[:limit] || 1000) list = Tag::Item.order(name: :asc).limit(params[:limit] || 1000)
results = [] results = []
list.each do |item| list.each do |item|
@ -76,14 +76,12 @@ class TagsController < ApplicationController
# POST /api/v1/tag_list # POST /api/v1/tag_list
def admin_create def admin_create
permission_check('admin.tag')
Tag::Item.lookup_by_name_and_create(params[:name]) Tag::Item.lookup_by_name_and_create(params[:name])
render json: {} render json: {}
end end
# PUT /api/v1/tag_list/:id # PUT /api/v1/tag_list/:id
def admin_rename def admin_rename
permission_check('admin.tag')
Tag::Item.rename( Tag::Item.rename(
id: params[:id], id: params[:id],
name: params[:name], name: params[:name],
@ -93,7 +91,6 @@ class TagsController < ApplicationController
# DELETE /api/v1/tag_list/:id # DELETE /api/v1/tag_list/:id
def admin_delete def admin_delete
permission_check('admin.tag')
Tag::Item.remove(params[:id]) Tag::Item.remove(params[:id])
render json: {} render json: {}
end end

View file

@ -1,45 +1,35 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TaskbarController < ApplicationController class TaskbarController < ApplicationController
prepend_before_action -> { authorize! }, only: %i[show update destroy]
prepend_before_action :authentication_check prepend_before_action :authentication_check
before_action :set_task_user_param, only: %i[create update]
def index def index
current_user_tasks = Taskbar.where(user_id: current_user.id) current_user_tasks = Taskbar.where(user_id: current_user.id)
model_index_render_result(current_user_tasks) model_index_render_result(current_user_tasks)
end end
def show def show
taskbar = Taskbar.find(params[:id])
access_to_taskbar(taskbar)
model_create_render(Taskbar, params) model_create_render(Taskbar, params)
end end
def create def create
task_user(params)
model_create_render(Taskbar, params) model_create_render(Taskbar, params)
end end
def update def update
taskbar = Taskbar.find(params[:id])
access_to_taskbar(taskbar)
task_user(params)
model_update_render(Taskbar, params) model_update_render(Taskbar, params)
end end
def destroy def destroy
taskbar = Taskbar.find(params[:id])
access_to_taskbar(taskbar)
model_destroy_render(Taskbar, params) model_destroy_render(Taskbar, params)
end end
private private
def access_to_taskbar(taskbar) def set_task_user_param
raise Exceptions::UnprocessableEntity, 'Not allowed to access this task.' if taskbar.user_id != current_user.id
end
def task_user(params)
params[:user_id] = current_user.id params[:user_id] = current_user.id
end end
end end

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TemplatesController < ApplicationController class TemplatesController < ApplicationController
prepend_before_action :authentication_check prepend_before_action { authentication_check && authorize! }
=begin =begin
@ -47,7 +47,6 @@ curl http://localhost/api/v1/templates.json -v -u #{login}:#{password}
=end =end
def index def index
permission_check(['admin.template', 'ticket.agent'])
model_index_render(Template, params) model_index_render(Template, params)
end end
@ -69,7 +68,6 @@ curl http://localhost/api/v1/templates/#{id}.json -v -u #{login}:#{password}
=end =end
def show def show
permission_check(['admin.template', 'ticket.agent'])
model_show_render(Template, params) model_show_render(Template, params)
end end
@ -97,7 +95,6 @@ curl http://localhost/api/v1/templates.json -v -u #{login}:#{password} -H "Conte
=end =end
def create def create
permission_check(['admin.template', 'ticket.agent'])
model_create_render(Template, params) model_create_render(Template, params)
end end
@ -125,7 +122,6 @@ curl http://localhost/api/v1/templates.json -v -u #{login}:#{password} -H "Conte
=end =end
def update def update
permission_check(['admin.template', 'ticket.agent'])
model_update_render(Template, params) model_update_render(Template, params)
end end
@ -143,7 +139,6 @@ curl http://localhost/api/v1/templates.json -v -u #{login}:#{password} -H "Conte
=end =end
def destroy def destroy
permission_check(['admin.template', 'ticket.agent'])
model_destroy_render(Template, params) model_destroy_render(Template, params)
end end
end end

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TextModulesController < ApplicationController class TextModulesController < ApplicationController
prepend_before_action :authentication_check prepend_before_action { authentication_check && authorize! }
=begin =begin
@ -49,7 +49,6 @@ curl http://localhost/api/v1/text_modules.json -v -u #{login}:#{password}
=end =end
def index def index
permission_check(['admin.text_module', 'ticket.agent'])
model_index_render(TextModule, params) model_index_render(TextModule, params)
end end
@ -71,7 +70,6 @@ curl http://localhost/api/v1/text_modules/#{id}.json -v -u #{login}:#{password}
=end =end
def show def show
permission_check(['admin.text_module', 'ticket.agent'])
model_show_render(TextModule, params) model_show_render(TextModule, params)
end end
@ -101,7 +99,6 @@ curl http://localhost/api/v1/text_modules.json -v -u #{login}:#{password} -H "Co
=end =end
def create def create
permission_check('admin.text_module')
model_create_render(TextModule, params) model_create_render(TextModule, params)
end end
@ -131,7 +128,6 @@ curl http://localhost/api/v1/text_modules.json -v -u #{login}:#{password} -H "Co
=end =end
def update def update
permission_check('admin.text_module')
model_update_render(TextModule, params) model_update_render(TextModule, params)
end end
@ -149,7 +145,6 @@ curl http://localhost/api/v1/text_modules.json -v -u #{login}:#{password} -H "Co
=end =end
def destroy def destroy
permission_check('admin.text_module')
model_destroy_render(TextModule, params) model_destroy_render(TextModule, params)
end end
@ -162,7 +157,6 @@ curl http://localhost/api/v1/text_modules.json -v -u #{login}:#{password} -H "Co
# @response_message 200 File download. # @response_message 200 File download.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_example def import_example
permission_check('admin.text_module')
csv_string = TextModule.csv_example( csv_string = TextModule.csv_example(
col_sep: params[:col_sep] || ',', col_sep: params[:col_sep] || ',',
) )
@ -185,7 +179,6 @@ curl http://localhost/api/v1/text_modules.json -v -u #{login}:#{password} -H "Co
# @response_message 201 Import started. # @response_message 201 Import started.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_start def import_start
permission_check('admin.text_module')
string = params[:data] string = params[:data]
if string.blank? && params[:file].present? if string.blank? && params[:file].present?
string = params[:file].read.force_encoding('utf-8') string = params[:file].read.force_encoding('utf-8')

View file

@ -4,18 +4,18 @@ class TicketArticlesController < ApplicationController
include CreatesTicketArticles include CreatesTicketArticles
include ClonesTicketArticleAttachments include ClonesTicketArticleAttachments
prepend_before_action -> { authorize! }, only: %i[index import_example import_start]
prepend_before_action :authentication_check prepend_before_action :authentication_check
# GET /articles # GET /articles
def index def index
permission_check('admin')
model_index_render(Ticket::Article, params) model_index_render(Ticket::Article, params)
end end
# GET /articles/1 # GET /articles/1
def show def show
article = Ticket::Article.find(params[:id]) article = Ticket::Article.find(params[:id])
access!(article, 'read') authorize!(article)
if response_expand? if response_expand?
result = article.attributes_with_association_names result = article.attributes_with_association_names
@ -35,15 +35,13 @@ class TicketArticlesController < ApplicationController
# GET /ticket_articles/by_ticket/1 # GET /ticket_articles/by_ticket/1
def index_by_ticket def index_by_ticket
ticket = Ticket.find(params[:id]) ticket = Ticket.find(params[:id])
access!(ticket, 'read') authorize!(ticket, :show?)
articles = [] articles = []
if response_expand? if response_expand?
ticket.articles.each do |article| ticket.articles.each do |article|
next if !authorized?(article, :show?)
# ignore internal article if customer is requesting
next if article.internal == true && current_user.permissions?('ticket.customer')
result = article.attributes_with_association_names result = article.attributes_with_association_names
articles.push result articles.push result
@ -57,9 +55,7 @@ class TicketArticlesController < ApplicationController
assets = {} assets = {}
record_ids = [] record_ids = []
ticket.articles.each do |article| ticket.articles.each do |article|
next if !authorized?(article, :show?)
# ignore internal article if customer is requesting
next if article.internal == true && current_user.permissions?('ticket.customer')
record_ids.push article.id record_ids.push article.id
assets = article.assets({}) assets = article.assets({})
@ -72,9 +68,7 @@ class TicketArticlesController < ApplicationController
end end
ticket.articles.each do |article| ticket.articles.each do |article|
next if !authorized?(article, :show?)
# ignore internal article if customer is requesting
next if article.internal == true && current_user.permissions?('ticket.customer')
articles.push article.attributes_with_association_names articles.push article.attributes_with_association_names
end end
@ -84,7 +78,7 @@ class TicketArticlesController < ApplicationController
# POST /articles # POST /articles
def create def create
ticket = Ticket.find(params[:ticket_id]) ticket = Ticket.find(params[:ticket_id])
access!(ticket, 'create') authorize!(ticket)
article = article_create(ticket, params) article = article_create(ticket, params)
if response_expand? if response_expand?
@ -105,11 +99,7 @@ class TicketArticlesController < ApplicationController
# PUT /articles/1 # PUT /articles/1
def update def update
article = Ticket::Article.find(params[:id]) article = Ticket::Article.find(params[:id])
access!(article, 'change') authorize!(article)
if !current_user.permissions?('ticket.agent') && !current_user.permissions?('admin')
raise Exceptions::NotAuthorized, 'Not authorized (ticket.agent or admin permission required)!'
end
clean_params = Ticket::Article.association_name_to_id_convert(params) clean_params = Ticket::Article.association_name_to_id_convert(params)
clean_params = Ticket::Article.param_cleanup(clean_params, true) clean_params = Ticket::Article.param_cleanup(clean_params, true)
@ -137,34 +127,15 @@ class TicketArticlesController < ApplicationController
# DELETE /api/v1/ticket_articles/:id # DELETE /api/v1/ticket_articles/:id
def destroy def destroy
article = Ticket::Article.find(params[:id]) article = Ticket::Article.find(params[:id])
access!(article, 'delete') authorize!(article)
article.destroy!
if current_user.permissions?('admin') render json: {}, status: :ok
article.destroy!
render json: {}, status: :ok
return
end
article_deletable =
current_user.permissions?('ticket.agent') &&
article.created_by_id == current_user.id &&
!article.type.communication?
raise Exceptions::NotAuthorized, 'Not authorized (admin permission required)!' if !article_deletable
if article_deletable && article.created_at >= 10.minutes.ago
article.destroy!
render json: {}, status: :ok
return
end
raise Exceptions::NotAuthorized, 'Articles can only be deleted within 10 minutes after creation.'
end end
# POST /ticket_attachment_upload_clone_by_article # POST /ticket_attachment_upload_clone_by_article
def ticket_attachment_upload_clone_by_article def ticket_attachment_upload_clone_by_article
article = Ticket::Article.find(params[:article_id]) article = Ticket::Article.find(params[:article_id])
access!(article.ticket, 'read') authorize!(article.ticket, :show?)
render json: { render json: {
attachments: article_attachments_clone(article), attachments: article_attachments_clone(article),
@ -174,7 +145,7 @@ class TicketArticlesController < ApplicationController
# GET /ticket_attachment/:ticket_id/:article_id/:id # GET /ticket_attachment/:ticket_id/:article_id/:id
def attachment def attachment
ticket = Ticket.lookup(id: params[:ticket_id]) ticket = Ticket.lookup(id: params[:ticket_id])
access!(ticket, 'read') authorize!(ticket, :show?)
article = Ticket::Article.find(params[:article_id]) article = Ticket::Article.find(params[:article_id])
if ticket.id != article.ticket_id if ticket.id != article.ticket_id
@ -185,7 +156,7 @@ class TicketArticlesController < ApplicationController
end end
ticket = article.ticket ticket = article.ticket
access!(ticket, 'read') authorize!(ticket, :show?)
end end
list = article.attachments || [] list = article.attachments || []
@ -226,7 +197,7 @@ class TicketArticlesController < ApplicationController
# GET /ticket_article_plain/1 # GET /ticket_article_plain/1
def article_plain def article_plain
article = Ticket::Article.find(params[:id]) article = Ticket::Article.find(params[:id])
access!(article, 'read') authorize!(article, :show?)
file = article.as_raw file = article.as_raw
@ -250,7 +221,6 @@ class TicketArticlesController < ApplicationController
# @response_message 200 File download. # @response_message 200 File download.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_example def import_example
permission_check('admin')
csv_string = Ticket::Article.csv_example( csv_string = Ticket::Article.csv_example(
col_sep: ',', col_sep: ',',
) )
@ -273,7 +243,6 @@ class TicketArticlesController < ApplicationController
# @response_message 201 Import started. # @response_message 201 Import started.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_start def import_start
permission_check('admin')
if Setting.get('import_mode') != true if Setting.get('import_mode') != true
raise 'Only can import tickets if system is in import mode.' raise 'Only can import tickets if system is in import mode.'
end end

View file

@ -1,35 +1,30 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TicketPrioritiesController < ApplicationController class TicketPrioritiesController < ApplicationController
prepend_before_action :authentication_check prepend_before_action { authentication_check && authorize! }
# GET /ticket_priorities # GET /ticket_priorities
def index def index
permission_check(['admin.object', 'ticket.agent', 'ticket.customer'])
model_index_render(Ticket::Priority, params) model_index_render(Ticket::Priority, params)
end end
# GET /ticket_priorities/1 # GET /ticket_priorities/1
def show def show
permission_check(['admin.object', 'ticket.agent', 'ticket.customer'])
model_show_render(Ticket::Priority, params) model_show_render(Ticket::Priority, params)
end end
# POST /ticket_priorities # POST /ticket_priorities
def create def create
permission_check('admin.object')
model_create_render(Ticket::Priority, params) model_create_render(Ticket::Priority, params)
end end
# PUT /ticket_priorities/1 # PUT /ticket_priorities/1
def update def update
permission_check('admin.object')
model_update_render(Ticket::Priority, params) model_update_render(Ticket::Priority, params)
end end
# DELETE /ticket_priorities/1 # DELETE /ticket_priorities/1
def destroy def destroy
permission_check('admin.object')
model_references_check(Ticket::Priority, params) model_references_check(Ticket::Priority, params)
model_destroy_render(Ticket::Priority, params) model_destroy_render(Ticket::Priority, params)
end end

View file

@ -1,37 +1,31 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TicketStatesController < ApplicationController class TicketStatesController < ApplicationController
prepend_before_action :authentication_check prepend_before_action { authentication_check && authorize! }
# GET /ticket_states # GET /ticket_states
def index def index
permission_check(['admin.object', 'ticket.agent', 'ticket.customer'])
model_index_render(Ticket::State, params) model_index_render(Ticket::State, params)
end end
# GET /ticket_states/1 # GET /ticket_states/1
def show def show
permission_check(['admin.object', 'ticket.agent', 'ticket.customer'])
model_show_render(Ticket::State, params) model_show_render(Ticket::State, params)
end end
# POST /ticket_states # POST /ticket_states
def create def create
permission_check('admin.object')
model_create_render(Ticket::State, params) model_create_render(Ticket::State, params)
end end
# PUT /ticket_states/1 # PUT /ticket_states/1
def update def update
permission_check('admin.object')
model_update_render(Ticket::State, params) model_update_render(Ticket::State, params)
end end
# DELETE /ticket_states/1 # DELETE /ticket_states/1
def destroy def destroy
permission_check('admin.object') model_references_check(Ticket::State, params)
return if model_references_check(Ticket::State, params)
model_destroy_render(Ticket::State, params) model_destroy_render(Ticket::State, params)
end end
end end

View file

@ -6,8 +6,8 @@ class TicketsController < ApplicationController
include ChecksUserAttributesByCurrentUserPermission include ChecksUserAttributesByCurrentUserPermission
include TicketStats include TicketStats
prepend_before_action -> { authorize! }, only: %i[selector import_example import_start]
prepend_before_action :authentication_check prepend_before_action :authentication_check
before_action :follow_up_possible_check, only: :update
# GET /api/v1/tickets # GET /api/v1/tickets
def index def index
@ -55,7 +55,7 @@ class TicketsController < ApplicationController
# GET /api/v1/tickets/1 # GET /api/v1/tickets/1
def show def show
ticket = Ticket.find(params[:id]) ticket = Ticket.find(params[:id])
access!(ticket, 'read') authorize!(ticket)
if response_expand? if response_expand?
result = ticket.attributes_with_association_names result = ticket.attributes_with_association_names
@ -221,7 +221,8 @@ class TicketsController < ApplicationController
# PUT /api/v1/tickets/1 # PUT /api/v1/tickets/1
def update def update
ticket = Ticket.find(params[:id]) ticket = Ticket.find(params[:id])
access!(ticket, 'change') authorize!(ticket, :follow_up?)
authorize!(ticket)
clean_params = Ticket.association_name_to_id_convert(params) clean_params = Ticket.association_name_to_id_convert(params)
clean_params = Ticket.param_cleanup(clean_params, true) clean_params = Ticket.param_cleanup(clean_params, true)
@ -269,9 +270,7 @@ class TicketsController < ApplicationController
# DELETE /api/v1/tickets/1 # DELETE /api/v1/tickets/1
def destroy def destroy
ticket = Ticket.find(params[:id]) ticket = Ticket.find(params[:id])
access!(ticket, 'delete') authorize!(ticket)
raise Exceptions::NotAuthorized, 'Not authorized (admin permission required)!' if !current_user.permissions?('admin')
ticket.destroy! ticket.destroy!
@ -296,7 +295,7 @@ class TicketsController < ApplicationController
# get ticket data # get ticket data
ticket = Ticket.find(params[:id]) ticket = Ticket.find(params[:id])
access!(ticket, 'read') authorize!(ticket, :show?)
# get history of ticket # get history of ticket
render json: ticket.history_get(true) render json: ticket.history_get(true)
@ -385,7 +384,7 @@ class TicketsController < ApplicationController
} }
return return
end end
access!(ticket_master, 'change') authorize!(ticket_master, :update?)
# check slave ticket # check slave ticket
ticket_slave = Ticket.find_by(id: params[:slave_ticket_id]) ticket_slave = Ticket.find_by(id: params[:slave_ticket_id])
@ -396,7 +395,7 @@ class TicketsController < ApplicationController
} }
return return
end end
access!(ticket_slave, 'change') authorize!(ticket_slave, :update?)
# merge ticket # merge ticket
ticket_slave.merge_to( ticket_slave.merge_to(
@ -415,11 +414,11 @@ class TicketsController < ApplicationController
# GET /api/v1/ticket_split # GET /api/v1/ticket_split
def ticket_split def ticket_split
ticket = Ticket.find(params[:ticket_id]) ticket = Ticket.find(params[:ticket_id])
access!(ticket, 'read') authorize!(ticket, :show?)
assets = ticket.assets({}) assets = ticket.assets({})
article = Ticket::Article.find(params[:article_id]) article = Ticket::Article.find(params[:article_id])
access!(article.ticket, 'read') authorize!(article.ticket, :show?)
assets = article.assets(assets) assets = article.assets(assets)
render json: { render json: {
@ -497,8 +496,6 @@ class TicketsController < ApplicationController
# GET /api/v1/tickets/selector # GET /api/v1/tickets/selector
def selector def selector
permission_check('admin.*')
ticket_count, tickets = Ticket.selectors(params[:condition], limit: 6, execution_time: true) ticket_count, tickets = Ticket.selectors(params[:condition], limit: 6, execution_time: true)
assets = {} assets = {}
@ -627,7 +624,6 @@ class TicketsController < ApplicationController
# @response_message 200 File download. # @response_message 200 File download.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_example def import_example
permission_check('admin')
csv_string = Ticket.csv_example( csv_string = Ticket.csv_example(
col_sep: ',', col_sep: ',',
) )
@ -650,7 +646,6 @@ class TicketsController < ApplicationController
# @response_message 201 Import started. # @response_message 201 Import started.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_start def import_start
permission_check('admin')
if Setting.get('import_mode') != true if Setting.get('import_mode') != true
raise 'Only can import tickets if system is in import mode.' raise 'Only can import tickets if system is in import mode.'
end end
@ -673,16 +668,6 @@ class TicketsController < ApplicationController
private private
def follow_up_possible_check
ticket = Ticket.find(params[:id])
return true if current_user.permissions?('ticket.agent') # agents can always reopen tickets, regardless of group configuration
return true if ticket.group.follow_up_possible != 'new_ticket' # check if the setting for follow_up_possible is disabled
return true if ticket.state.name != 'closed' # check if the ticket state is already closed
raise Exceptions::UnprocessableEntity, 'Cannot follow-up on a closed ticket. Please create a new ticket.'
end
def ticket_all(ticket) def ticket_all(ticket)
# get attributes to update # get attributes to update
@ -698,9 +683,7 @@ class TicketsController < ApplicationController
# get related users # get related users
article_ids = [] article_ids = []
ticket.articles.each do |article| ticket.articles.each do |article|
next if !authorized?(article, :show?)
# ignore internal article if customer is requesting
next if article.internal == true && current_user.permissions?('ticket.customer')
article_ids.push article.id article_ids.push article.id
assets = article.assets(assets) assets = article.assets(assets)

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TimeAccountingsController < ApplicationController class TimeAccountingsController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.time_accounting') } prepend_before_action { authentication_check && authorize! }
def by_ticket def by_ticket

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TranslationsController < ApplicationController class TranslationsController < ApplicationController
prepend_before_action :authentication_check, except: [:lang] prepend_before_action -> { authentication_check && authorize! }, except: [:lang]
# GET /translations/lang/:locale # GET /translations/lang/:locale
def lang def lang
@ -10,7 +10,6 @@ class TranslationsController < ApplicationController
# PUT /translations/push # PUT /translations/push
def push def push
permission_check('admin.translation')
start = Time.zone.now start = Time.zone.now
Translation.push(params[:locale]) Translation.push(params[:locale])
if start > Time.zone.now - 4.seconds if start > Time.zone.now - 4.seconds
@ -21,51 +20,43 @@ class TranslationsController < ApplicationController
# POST /translations/sync/:locale # POST /translations/sync/:locale
def sync def sync
permission_check('admin.translation')
Translation.load(params[:locale]) Translation.load(params[:locale])
render json: { message: 'ok' }, status: :ok render json: { message: 'ok' }, status: :ok
end end
# POST /translations/reset # POST /translations/reset
def reset def reset
permission_check('admin.translation')
Translation.reset(params[:locale]) Translation.reset(params[:locale])
render json: { message: 'ok' }, status: :ok render json: { message: 'ok' }, status: :ok
end end
# GET /translations/admin/lang/:locale # GET /translations/admin/lang/:locale
def admin def admin
permission_check('admin.translation')
render json: Translation.lang(params[:locale], true) render json: Translation.lang(params[:locale], true)
end end
# GET /translations # GET /translations
def index def index
permission_check('admin.translation')
model_index_render(Translation, params) model_index_render(Translation, params)
end end
# GET /translations/1 # GET /translations/1
def show def show
permission_check('admin.translation')
model_show_render(Translation, params) model_show_render(Translation, params)
end end
# POST /translations # POST /translations
def create def create
permission_check('admin.translation')
model_create_render(Translation, params) model_create_render(Translation, params)
end end
# PUT /translations/1 # PUT /translations/1
def update def update
permission_check('admin.translation')
model_update_render(Translation, params) model_update_render(Translation, params)
end end
# DELETE /translations/1 # DELETE /translations/1
def destroy def destroy
permission_check('admin.translation')
model_destroy_render(Translation, params) model_destroy_render(Translation, params)
end end
end end

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TriggersController < ApplicationController class TriggersController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.trigger') } prepend_before_action { authentication_check && authorize! }
def index def index
model_index_render(Trigger, params) model_index_render(Trigger, params)

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class UserAccessTokenController < ApplicationController class UserAccessTokenController < ApplicationController
prepend_before_action { authentication_check(permission: 'user_preferences.access_token') } prepend_before_action { authentication_check && authorize! }
=begin =begin

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class UserDevicesController < ApplicationController class UserDevicesController < ApplicationController
prepend_before_action { authentication_check(permission: 'user_preferences.device') } prepend_before_action { authentication_check && authorize! }
def index def index
devices = UserDevice.where(user_id: current_user.id).order(updated_at: :desc, name: :asc) devices = UserDevice.where(user_id: current_user.id).order(updated_at: :desc, name: :asc)

View file

@ -3,6 +3,7 @@
class UsersController < ApplicationController class UsersController < ApplicationController
include ChecksUserAttributesByCurrentUserPermission include ChecksUserAttributesByCurrentUserPermission
prepend_before_action -> { authorize! }, only: %i[import_example import_start search history]
prepend_before_action :authentication_check, except: %i[create password_reset_send password_reset_verify image] prepend_before_action :authentication_check, except: %i[create password_reset_send password_reset_verify image]
prepend_before_action :authentication_check_only, only: [:create] prepend_before_action :authentication_check_only, only: [:create]
@ -27,12 +28,7 @@ class UsersController < ApplicationController
per_page = 500 per_page = 500
end end
# only allow customer to fetch him self users = policy_scope(User).order(id: :asc).offset(offset).limit(per_page)
users = if !current_user.permissions?(['admin.user', 'ticket.agent'])
User.where(id: current_user.id).order(id: :asc).offset(offset).limit(per_page)
else
User.all.order(id: :asc).offset(offset).limit(per_page)
end
if response_expand? if response_expand?
list = [] list = []
@ -78,7 +74,7 @@ class UsersController < ApplicationController
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def show def show
user = User.find(params[:id]) user = User.find(params[:id])
access!(user, 'read') authorize!(user)
if response_expand? if response_expand?
result = user.attributes_with_association_names result = user.attributes_with_association_names
@ -263,7 +259,7 @@ class UsersController < ApplicationController
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def update def update
user = User.find(params[:id]) user = User.find(params[:id])
access!(user, 'change') authorize!(user)
# permission check # permission check
check_attributes_by_current_user_permission(params) check_attributes_by_current_user_permission(params)
@ -312,7 +308,7 @@ class UsersController < ApplicationController
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def destroy def destroy
user = User.find(params[:id]) user = User.find(params[:id])
access!(user, 'delete') authorize!(user)
model_references_check(User, params) model_references_check(User, params)
model_destroy_render(User, params) model_destroy_render(User, params)
@ -367,8 +363,6 @@ class UsersController < ApplicationController
# @response_message 200 [Array<User>] A list of User records matching the search term. # @response_message 200 [Array<User>] A list of User records matching the search term.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def search def search
raise Exceptions::NotAuthorized if !current_user.permissions?(['ticket.agent', 'admin.user'])
per_page = params[:per_page] || params[:limit] || 100 per_page = params[:per_page] || params[:limit] || 100
per_page = per_page.to_i per_page = per_page.to_i
if per_page > 500 if per_page > 500
@ -472,8 +466,6 @@ class UsersController < ApplicationController
# @response_message 200 [History] The History records of the requested User record. # @response_message 200 [History] The History records of the requested User record.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def history def history
raise Exceptions::NotAuthorized if !current_user.permissions?(['admin.user', 'ticket.agent'])
# get user data # get user data
user = User.find(params[:id]) user = User.find(params[:id])
@ -775,8 +767,6 @@ curl http://localhost/api/v1/users/preferences -v -u #{login}:#{password} -H "Co
=end =end
def preferences def preferences
raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
preferences_params = params.except(:controller, :action) preferences_params = params.except(:controller, :action)
if preferences_params.present? if preferences_params.present?
@ -816,8 +806,6 @@ curl http://localhost/api/v1/users/out_of_office -v -u #{login}:#{password} -H "
=end =end
def out_of_office def out_of_office
raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
user = User.find(current_user.id) user = User.find(current_user.id)
user.with_lock do user.with_lock do
user.assign_attributes( user.assign_attributes(
@ -854,8 +842,6 @@ curl http://localhost/api/v1/users/account -v -u #{login}:#{password} -H "Conten
=end =end
def account_remove def account_remove
raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
# provider + uid to remove # provider + uid to remove
raise Exceptions::UnprocessableEntity, 'provider needed!' if !params[:provider] raise Exceptions::UnprocessableEntity, 'provider needed!' if !params[:provider]
raise Exceptions::UnprocessableEntity, 'uid needed!' if !params[:uid] raise Exceptions::UnprocessableEntity, 'uid needed!' if !params[:uid]
@ -934,8 +920,6 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
=end =end
def avatar_new def avatar_new
return if !valid_session_with_user
# get & validate image # get & validate image
file_full = StaticAssets.data_url_attributes(params[:avatar_full]) file_full = StaticAssets.data_url_attributes(params[:avatar_full])
file_resize = StaticAssets.data_url_attributes(params[:avatar_resize]) file_resize = StaticAssets.data_url_attributes(params[:avatar_resize])
@ -963,8 +947,6 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
end end
def avatar_set_default def avatar_set_default
return if !valid_session_with_user
# get & validate image # get & validate image
raise Exceptions::UnprocessableEntity, 'No id of avatar!' if !params[:id] raise Exceptions::UnprocessableEntity, 'No id of avatar!' if !params[:id]
@ -979,8 +961,6 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
end end
def avatar_destroy def avatar_destroy
return if !valid_session_with_user
# get & validate image # get & validate image
raise Exceptions::UnprocessableEntity, 'No id of avatar!' if !params[:id] raise Exceptions::UnprocessableEntity, 'No id of avatar!' if !params[:id]
@ -996,8 +976,6 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
end end
def avatar_list def avatar_list
return if !valid_session_with_user
# list of avatars # list of avatars
result = Avatar.list('User', current_user.id) result = Avatar.list('User', current_user.id)
render json: { avatars: result }, status: :ok render json: { avatars: result }, status: :ok
@ -1012,7 +990,6 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
# @response_message 200 File download. # @response_message 200 File download.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_example def import_example
permission_check('admin.user')
send_data( send_data(
User.csv_example, User.csv_example,
filename: 'user-example.csv', filename: 'user-example.csv',
@ -1031,7 +1008,6 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
# @response_message 201 Import started. # @response_message 201 Import started.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def import_start def import_start
permission_check('admin.user')
string = params[:data] string = params[:data]
if string.blank? && params[:file].present? if string.blank? && params[:file].present?
string = params[:file].read.force_encoding('utf-8') string = params[:file].read.force_encoding('utf-8')

View file

@ -1,7 +1,8 @@
# Copyright (C) 2012-2017 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2017 Zammad Foundation, http://zammad-foundation.org/
class VersionController < ApplicationController class VersionController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.version') }
prepend_before_action { authentication_check && authorize! }
# GET /api/v1/version # GET /api/v1/version
def index def index

View file

@ -10,7 +10,6 @@ class Organization < ApplicationModel
include ChecksHtmlSanitized include ChecksHtmlSanitized
include HasObjectManagerAttributesValidation include HasObjectManagerAttributesValidation
include Organization::ChecksAccess
include Organization::Assets include Organization::Assets
include Organization::Search include Organization::Search
include Organization::SearchIndex include Organization::SearchIndex

View file

@ -1,51 +0,0 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class Organization
module ChecksAccess
extend ActiveSupport::Concern
# Checks the given access of a given user for an organization.
#
# @param [User] The user that will be checked for given access.
# @param [String] The access that should get checked.
#
# @example
# organization.access?(user, 'read')
# #=> true
#
# @return [Boolean]
def access?(user, access)
# check customer
if user.permissions?('ticket.customer')
# access ok if its own organization
return false if access != 'read'
return false if !user.organization_id
return id == user.organization_id
end
# check agent
return true if user.permissions?('admin')
return true if user.permissions?('ticket.agent')
false
end
# Checks the given access of a given user for an organization and fails with an exception.
#
# @param (see Organization#access?)
#
# @example
# organization.access!(user, 'read')
#
# @raise [NotAuthorized] Gets raised if given user doesn't have the given access.
#
# @return [nil]
def access!(user, access)
return if access?(user, access)
raise Exceptions::NotAuthorized
end
end
end

View file

@ -76,12 +76,11 @@ class RecentView < ApplicationModel
end end
def self.access(object, o_id, user) def self.access(object, o_id, user)
object.to_s record = object.to_s
.constantize .safe_constantize
.try(:lookup, { id: o_id }) .try(:lookup, { id: o_id })
.try(:access?, user, 'read')
rescue NameError Pundit.policy(user, record).try(:show?)
false
end end
=begin =begin

View file

@ -13,7 +13,6 @@ class Ticket < ApplicationModel
include HasOnlineNotifications include HasOnlineNotifications
include HasKarmaActivityLog include HasKarmaActivityLog
include HasLinks include HasLinks
include Ticket::ChecksAccess
include HasObjectManagerAttributesValidation include HasObjectManagerAttributesValidation
include Ticket::Escalation include Ticket::Escalation

View file

@ -8,7 +8,6 @@ class Ticket::Article < ApplicationModel
include CanCsvImport include CanCsvImport
include HasObjectManagerAttributesValidation include HasObjectManagerAttributesValidation
include Ticket::Article::ChecksAccess
include Ticket::Article::Assets include Ticket::Article::Assets
belongs_to :ticket, optional: true belongs_to :ticket, optional: true

View file

@ -1,43 +0,0 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class Ticket
class Article
module ChecksAccess
extend ActiveSupport::Concern
# Checks the given access of a given user for a ticket article.
#
# @param [User] The user that will be checked for given access.
# @param [String] The access that should get checked.
#
# @example
# article.access?(user, 'read')
# #=> true
#
# @return [Boolean]
def access?(user, access)
if user.permissions?('ticket.customer')
return false if internal == true
end
ticket = Ticket.lookup(id: ticket_id)
ticket.access?(user, access)
end
# Checks the given access of a given user for a ticket article and fails with an exception.
#
# @param (see Ticket::Article#access?)
#
# @example
# article.access!(user, 'read')
#
# @raise [NotAuthorized] Gets raised if given user doesn't have the given access.
#
# @return [nil]
def access!(user, access)
return if access?(user, access)
raise Exceptions::NotAuthorized
end
end
end
end

View file

@ -1,57 +0,0 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class Ticket
module ChecksAccess
extend ActiveSupport::Concern
# Checks the given access of a given user for a ticket.
#
# @param [User] The user that will be checked for given access.
# @param [String] The access that should get checked.
#
# @example
# ticket.access?(user, 'read')
# #=> true
#
# @return [Boolean]
def access?(user, access)
# check customer
if user.permissions?('ticket.customer')
# access ok if its own ticket
return true if customer_id == user.id
# check organization ticket access
return false if organization_id.blank?
return false if user.organization_id.blank?
return false if organization_id != user.organization_id
return organization.shared?
end
# check agent
# access if requestor is owner
return true if owner_id == user.id
# access if requestor is in group
user.group_access?(group.id, access)
end
# Checks the given access of a given user for a ticket and fails with an exception.
#
# @param (see Ticket#access?)
#
# @example
# ticket.access!(user, 'read')
#
# @raise [NotAuthorized] Gets raised if given user doesn't have the given access.
#
# @return [nil]
def access!(user, access)
return if access?(user, access)
raise Exceptions::NotAuthorized
end
end
end

View file

@ -79,27 +79,7 @@ returns
# add permission check # add permission check
if data[:permission] if data[:permission]
return if !user.permissions?(data[:permission]) return if !token.permissions?(data[:permission])
return if !token.preferences[:permission]
local_permissions = data[:permission]
if data[:permission].class != Array
local_permissions = [data[:permission]]
end
match = false
local_permissions.each do |local_permission|
local_permissions = Permission.with_parents(local_permission)
local_permissions.each do |local_permission_name|
next if !token.preferences[:permission].include?(local_permission_name)
match = true
break
end
next if !match
break
end
return if !match
end end
# return token user # return token user
@ -119,6 +99,17 @@ cleanup old token
true true
end end
def permissions?(permissions)
return false if !user.permissions?(permissions)
return false if preferences[:permission].blank?
Array(permissions).any? do |parentless|
Permission.with_parents(parentless).any? do |permission|
preferences[:permission].include?(permission)
end
end
end
private private
def generate_token def generate_token

View file

@ -14,7 +14,6 @@ class User < ApplicationModel
include HasObjectManagerAttributesValidation include HasObjectManagerAttributesValidation
include HasTicketCreateScreenImpact include HasTicketCreateScreenImpact
include User::HasTicketCreateScreenImpact include User::HasTicketCreateScreenImpact
include User::ChecksAccess
include User::Assets include User::Assets
include User::Search include User::Search
include User::SearchIndex include User::SearchIndex
@ -421,14 +420,10 @@ returns
=end =end
def permissions?(key) def permissions?(key)
keys = key Array(key).each do |local_key|
if key.class == String
keys = [key]
end
keys.each do |local_key|
list = [] list = []
if local_key.match?(/\.\*$/) if local_key.match?(/\.\*$/)
local_key.sub!('.*', '.%') local_key = local_key.sub('.*', '.%')
permissions = ::Permission.with_parents(local_key) permissions = ::Permission.with_parents(local_key)
list = ::Permission.select('preferences').joins(:roles).where('roles.id IN (?) AND roles.active = ? AND (permissions.name IN (?) OR permissions.name LIKE ?) AND permissions.active = ?', role_ids, true, permissions, local_key, true).pluck(:preferences) list = ::Permission.select('preferences').joins(:roles).where('roles.id IN (?) AND roles.active = ? AND (permissions.name IN (?) OR permissions.name LIKE ?) AND permissions.active = ?', role_ids, true, permissions, local_key, true).pluck(:preferences)
else else

View file

@ -1,74 +0,0 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class User
module ChecksAccess
extend ActiveSupport::Concern
# Checks the given access of a given user for another user.
#
# @param [User] The user that will be checked for given access.
# @param [String] The access that should get checked.
#
# @example
# user.access?(user, 'read')
# #=> true
#
# @return [Boolean]
def access?(requester, access)
# full admins can do whatever they want
return true if requester.permissions?('admin')
send("#{access}able_by?".to_sym, requester)
end
# Checks the given access of a given user for another user and fails with an exception.
#
# @param (see User#access?)
#
# @example
# user.access!(user, 'read')
#
# @raise [NotAuthorized] Gets raised if given user doesn't have the given access.
#
# @return [nil]
def access!(user, access)
return if access?(user, access)
raise Exceptions::NotAuthorized
end
private
def readable_by?(requester)
return true if own_account?(requester)
return true if requester.permissions?('admin.*')
return true if requester.permissions?('ticket.agent')
# check same organization for customers
return false if !requester.permissions?('ticket.customer')
same_organization?(requester)
end
def changeable_by?(requester)
return true if requester.permissions?('admin.user')
# allow agents to change customers
return false if !requester.permissions?('ticket.agent')
permissions?('ticket.customer')
end
def deleteable_by?(requester)
requester.permissions?('admin.user')
end
def own_account?(requester)
id == requester.id
end
def same_organization?(requester)
return false if organization_id.blank?
return false if requester.organization_id.blank?
organization_id == requester.organization_id
end
end
end

View file

@ -0,0 +1,19 @@
class ApplicationPolicy
include PunditPolicy
attr_reader :record
def initialize_context(record)
@record = record
end
class Scope
include PunditPolicy
attr_reader :scope
def initialize_context(scope)
@scope = scope
end
end
end

View file

@ -0,0 +1,33 @@
class Controllers::ApplicationControllerPolicy < ApplicationPolicy
class_attribute(:action_permissions_map, default: {})
def self.inherited(subclass)
subclass.action_permissions_map = action_permissions_map.deep_dup
end
def self.default_permit!(permissions)
action_permissions_map.default = permissions
end
def self.permit!(actions, to:)
Array(actions).each do |action|
action_permissions_map[:"#{action}?"] = to
end
end
def method_missing(missing_method, *)
case (permission = action_permissions_map[missing_method])
when String, Array
user.permissions!(permission) || true
when Proc
user.permissions!(instance_exec(&permission)) || true
else
super
end
end
def respond_to_missing?(missing_method)
action_permissions_map[missing_method] || super
end
end

View file

@ -0,0 +1,3 @@
class Controllers::ApplicationsControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('admin.api')
end

View file

@ -0,0 +1,3 @@
class Controllers::CalendarSubscriptionsControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('user_preferences.calendar')
end

View file

@ -0,0 +1,4 @@
class Controllers::CalendarsControllerPolicy < Controllers::ApplicationControllerPolicy
permit! :timezones, to: 'admin'
default_permit!('admin.calendar')
end

View file

@ -0,0 +1,3 @@
class Controllers::ChannelsEmailControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('admin.channel_email')
end

View file

@ -0,0 +1,3 @@
class Controllers::ChannelsFacebookControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('admin.channel_facebook')
end

View file

@ -0,0 +1,3 @@
class Controllers::ChannelsSmsControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('admin.channel_sms')
end

View file

@ -0,0 +1,3 @@
class Controllers::ChannelsTelegramControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('admin.channel_telegram')
end

View file

@ -0,0 +1,3 @@
class Controllers::ChannelsTwitterControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('admin.channel_twitter')
end

View file

@ -0,0 +1,3 @@
class Controllers::ChatSessionsControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('chat.agent')
end

View file

@ -0,0 +1,3 @@
class Controllers::ChatsControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('admin.channel_chat')
end

View file

@ -0,0 +1,3 @@
class Controllers::CtiControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('cti.agent')
end

View file

@ -0,0 +1,4 @@
class Controllers::EmailAddressesControllerPolicy < Controllers::ApplicationControllerPolicy
permit! %i[index show], to: ['ticket.agent', 'admin.channel_email']
default_permit!('admin.channel_email')
end

View file

@ -0,0 +1,16 @@
class Controllers::ExternalCredentialsControllerPolicy < Controllers::ApplicationControllerPolicy
permit! :index, to: 'admin'
default_permit! -> { "admin.channel_#{provider_name}" }
private
def provider_name
@provider_name ||= begin
if record.params[:id].present?
ExternalCredential.find(record.params[:id]).name
else
record.params[:provider] || record.params[:name]
end
end
end
end

View file

@ -0,0 +1,3 @@
class Controllers::FirstStepsControllerPolicy < Controllers::ApplicationControllerPolicy
permit! %i[index test_ticket], to: ['ticket.agent', 'admin']
end

View file

@ -0,0 +1,28 @@
class Controllers::FormControllerPolicy < Controllers::ApplicationControllerPolicy
def configuration?
authorized?
end
def submit?
authorized?
end
def test?
record.params[:test] && user&.permissions?('admin.channel_formular')
end
private
def authorized?
test? || enabled?
end
def user_required?
false
end
def enabled?
Setting.get('form_ticket_create')
end
end

View file

@ -0,0 +1,3 @@
class Controllers::GettingStartedControllerPolicy < Controllers::ApplicationControllerPolicy
permit! :base, to: 'admin.wizard'
end

View file

@ -0,0 +1,3 @@
class Controllers::GroupsControllerPolicy < Controllers::ApplicationControllerPolicy
default_permit!('admin.group')
end

Some files were not shown because too many files have changed in this diff Show more