diff --git a/app/controllers/activity_stream_controller.rb b/app/controllers/activity_stream_controller.rb index 8d432e2cb..bd9c99e2b 100644 --- a/app/controllers/activity_stream_controller.rb +++ b/app/controllers/activity_stream_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ActivityStreamController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /api/v1/activity_stream def show diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index df8dd20b0..a29ee8f05 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,8 +4,6 @@ require 'exceptions' class ApplicationController < ActionController::Base include ErrorHandling - # http_basic_authenticate_with :name => "test", :password => "ttt" - helper_method :current_user, :authentication_check, :config_frontend, @@ -17,36 +15,53 @@ class ApplicationController < ActionController::Base :model_index_render skip_before_action :verify_authenticity_token - before_action :transaction_begin, :set_user, :session_update, :user_device_check, :cors_preflight_check - after_action :transaction_end, :http_log, :set_access_control_headers + before_action :verify_csrf_token, :transaction_begin, :set_user, :session_update, :user_device_check, :cors_preflight_check + after_action :transaction_end, :http_log, :set_access_control_headers, :set_csrf_token_headers # For all responses in this controller, return the CORS access control headers. def set_access_control_headers + return if @_auth_type != 'token_auth' && @_auth_type != 'basic_auth' + set_access_control_headers_execute + end + + def set_access_control_headers_execute headers['Access-Control-Allow-Origin'] = '*' - headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS' + headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, PATCH, OPTIONS' headers['Access-Control-Max-Age'] = '1728000' headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Accept-Language' - headers['Access-Control-Allow-Credentials'] = 'true' end # If this is a preflight OPTIONS request, then short-circuit the # request, return only the necessary headers and return an empty # text/plain. - def cors_preflight_check + return true if @_auth_type != 'token_auth' && @_auth_type != 'basic_auth' + cors_preflight_check_execute + end - return if request.method != 'OPTIONS' - + def cors_preflight_check_execute + return true if request.method != 'OPTIONS' headers['Access-Control-Allow-Origin'] = '*' - headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS' + headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, PATCH, OPTIONS' headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Accept-Language' headers['Access-Control-Max-Age'] = '1728000' - headers['Access-Control-Allow-Credentials'] = 'true' render text: '', content_type: 'text/plain' - false end + def set_csrf_token_headers + return true if @_auth_type.present? && @_auth_type != 'session' + headers['CSRF-TOKEN'] = form_authenticity_token + end + + def verify_csrf_token + return true if request.method != 'POST' && request.method != 'PUT' && request.method != 'DELETE' && request.method != 'PATCH' + return true if @_auth_type == 'token_auth' || @_auth_type == 'basic_auth' + return true if valid_authenticity_token?(session, params[:authenticity_token] || request.headers['X-CSRF-Token']) + logger.info 'CSRF token verification failed' + raise Exceptions::NotAuthorized, 'CSRF token verification failed!' + end + def http_log_config(config) @http_log_support = config end @@ -74,8 +89,9 @@ class ApplicationController < ActionController::Base @_current_user = User.lookup(id: session[:user_id]) end - def current_user_set(user) + def current_user_set(user, auth_type = 'session') session[:user_id] = user.id + @_auth_type = auth_type @_current_user = user set_user end @@ -224,7 +240,7 @@ class ApplicationController < ActionController::Base ) end - def authentication_check_only(auth_param) + def authentication_check_only(auth_param = {}) #logger.debug 'authentication_check' #logger.debug params.inspect #logger.debug session.inspect @@ -336,7 +352,7 @@ class ApplicationController < ActionController::Base raise Exceptions::NotAuthorized, 'Not authorized (user)!' end - current_user_set(user) + current_user_set(user, auth_type) user_device_log(user, auth_type) logger.debug "#{auth_type} for '#{user.login}'" true diff --git a/app/controllers/applications_controller.rb b/app/controllers/applications_controller.rb index 1b44c54c2..49c106310 100644 --- a/app/controllers/applications_controller.rb +++ b/app/controllers/applications_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ApplicationsController < ApplicationController - before_action { authentication_check(permission: 'admin.api') } + prepend_before_action { authentication_check(permission: 'admin.api') } def index all = Doorkeeper::Application.all diff --git a/app/controllers/calendar_subscriptions_controller.rb b/app/controllers/calendar_subscriptions_controller.rb index 0b4ec1200..1c8d34d50 100644 --- a/app/controllers/calendar_subscriptions_controller.rb +++ b/app/controllers/calendar_subscriptions_controller.rb @@ -3,7 +3,7 @@ require 'icalendar' class CalendarSubscriptionsController < ApplicationController - before_action { authentication_check( { basic_auth_promt: true, permission: 'user_preferences.calendar' } ) } + prepend_before_action { authentication_check( { basic_auth_promt: true, permission: 'user_preferences.calendar' } ) } # @path [GET] /calendar_subscriptions # diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index 01240e53d..d2169fae8 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class CalendarsController < ApplicationController - before_action { authentication_check(permission: 'admin.calendar') } + prepend_before_action { authentication_check(permission: 'admin.calendar') } def index diff --git a/app/controllers/channels_email_controller.rb b/app/controllers/channels_email_controller.rb index 8dbc68224..8056c897c 100644 --- a/app/controllers/channels_email_controller.rb +++ b/app/controllers/channels_email_controller.rb @@ -1,10 +1,9 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ChannelsEmailController < ApplicationController - before_action :authentication_check + prepend_before_action { authentication_check(permission: 'admin.channel_email') } def index - permission_check('admin.channel_email') system_online_service = Setting.get('system_online_service') account_channel_ids = [] notification_channel_ids = [] @@ -54,9 +53,6 @@ class ChannelsEmailController < ApplicationController def probe - # check admin permissions - permission_check('admin.channel_email') - # probe settings based on email and password result = EmailHelper::Probe.full( email: params[:email], @@ -74,9 +70,6 @@ class ChannelsEmailController < ApplicationController def outbound - # check admin permissions - permission_check('admin.channel_email') - # verify access return if params[:channel_id] && !check_access(params[:channel_id]) @@ -86,9 +79,6 @@ class ChannelsEmailController < ApplicationController def inbound - # check admin permissions - permission_check('admin.channel_email') - # verify access return if params[:channel_id] && !check_access(params[:channel_id]) @@ -103,9 +93,6 @@ class ChannelsEmailController < ApplicationController def verify - # check admin permissions - permission_check('admin.channel_email') - email = params[:email] || params[:meta][:email] email = email.downcase channel_id = params[:channel_id] @@ -195,7 +182,6 @@ class ChannelsEmailController < ApplicationController end def enable - permission_check('admin.channel_email') channel = Channel.find_by(id: params[:id], area: 'Email::Account') channel.active = true channel.save! @@ -203,7 +189,6 @@ class ChannelsEmailController < ApplicationController end def disable - permission_check('admin.channel_email') channel = Channel.find_by(id: params[:id], area: 'Email::Account') channel.active = false channel.save! @@ -211,7 +196,6 @@ class ChannelsEmailController < ApplicationController end def destroy - permission_check('admin.channel_email') channel = Channel.find_by(id: params[:id], area: 'Email::Account') channel.destroy render json: {} @@ -229,9 +213,6 @@ class ChannelsEmailController < ApplicationController check_online_service - # check admin permissions - permission_check('admin.channel_email') - adapter = params[:adapter].downcase email = Setting.get('notification_sender') diff --git a/app/controllers/channels_facebook_controller.rb b/app/controllers/channels_facebook_controller.rb index b4254a5a1..c0596598a 100644 --- a/app/controllers/channels_facebook_controller.rb +++ b/app/controllers/channels_facebook_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ChannelsFacebookController < ApplicationController - before_action { authentication_check(permission: 'admin.channel_facebook') } + prepend_before_action { authentication_check(permission: 'admin.channel_facebook') } def index assets = {} diff --git a/app/controllers/channels_telegram_controller.rb b/app/controllers/channels_telegram_controller.rb index cd40fc68c..639201767 100644 --- a/app/controllers/channels_telegram_controller.rb +++ b/app/controllers/channels_telegram_controller.rb @@ -1,7 +1,8 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ChannelsTelegramController < ApplicationController - before_action -> { authentication_check(permission: 'admin.channel_telegram') }, except: [:webhook] + prepend_before_action -> { authentication_check(permission: 'admin.channel_telegram') }, except: [:webhook] + skip_before_action :verify_csrf_token, only: [:webhook] def index assets = {} diff --git a/app/controllers/channels_twitter_controller.rb b/app/controllers/channels_twitter_controller.rb index b4bf0ec90..e2fe2a821 100644 --- a/app/controllers/channels_twitter_controller.rb +++ b/app/controllers/channels_twitter_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ChannelsTwitterController < ApplicationController - before_action { authentication_check(permission: 'admin.channel_twitter') } + prepend_before_action { authentication_check(permission: 'admin.channel_twitter') } def index assets = {} diff --git a/app/controllers/chats_controller.rb b/app/controllers/chats_controller.rb index ef7379105..d2f0e5315 100644 --- a/app/controllers/chats_controller.rb +++ b/app/controllers/chats_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ChatsController < ApplicationController - before_action { authentication_check(permission: 'admin.chat') } + prepend_before_action { authentication_check(permission: 'admin.chat') } def index chat_ids = [] diff --git a/app/controllers/cti_controller.rb b/app/controllers/cti_controller.rb index 1dada0b1b..61383428b 100644 --- a/app/controllers/cti_controller.rb +++ b/app/controllers/cti_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class CtiController < ApplicationController - before_action { authentication_check(permission: 'cti.agent') } + prepend_before_action { authentication_check(permission: 'cti.agent') } # list current caller log def index diff --git a/app/controllers/email_addresses_controller.rb b/app/controllers/email_addresses_controller.rb index 22ccf94cc..382ccbd9c 100644 --- a/app/controllers/email_addresses_controller.rb +++ b/app/controllers/email_addresses_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class EmailAddressesController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check =begin diff --git a/app/controllers/external_credentials_controller.rb b/app/controllers/external_credentials_controller.rb index 8e25702fb..e79d32579 100644 --- a/app/controllers/external_credentials_controller.rb +++ b/app/controllers/external_credentials_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ExternalCredentialsController < ApplicationController - before_action { authentication_check(permission: ['admin.channel_twitter', 'admin.channel_facebook']) } + prepend_before_action { authentication_check(permission: ['admin.channel_twitter', 'admin.channel_facebook']) } def index model_index_render(ExternalCredential, params) diff --git a/app/controllers/first_steps_controller.rb b/app/controllers/first_steps_controller.rb index c0084c501..9136a5eb4 100644 --- a/app/controllers/first_steps_controller.rb +++ b/app/controllers/first_steps_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class FirstStepsController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check def index return if !access? diff --git a/app/controllers/form_controller.rb b/app/controllers/form_controller.rb index 5732ff023..13804e9d6 100644 --- a/app/controllers/form_controller.rb +++ b/app/controllers/form_controller.rb @@ -1,6 +1,9 @@ # Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/ class FormController < ApplicationController + skip_before_action :verify_csrf_token + before_action :cors_preflight_check_execute + after_action :set_access_control_headers_execute def config return if !enabled? diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index a1abb05d2..7e8291198 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class GroupsController < ApplicationController - before_action { authentication_check(permission: 'admin.group') } + prepend_before_action { authentication_check(permission: 'admin.group') } =begin diff --git a/app/controllers/http_logs_controller.rb b/app/controllers/http_logs_controller.rb index 29b889ea7..ccbe61b90 100644 --- a/app/controllers/http_logs_controller.rb +++ b/app/controllers/http_logs_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class HttpLogsController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /http_logs/:facility def index diff --git a/app/controllers/integration/sipgate_controller.rb b/app/controllers/integration/sipgate_controller.rb index 69ae1c113..88524d1ed 100644 --- a/app/controllers/integration/sipgate_controller.rb +++ b/app/controllers/integration/sipgate_controller.rb @@ -3,7 +3,7 @@ require 'builder' class Integration::SipgateController < ApplicationController - + skip_before_action :verify_csrf_token before_action :check_configured # notify about inbound call / block inbound call diff --git a/app/controllers/jobs_controller.rb b/app/controllers/jobs_controller.rb index 660d6c2b8..b80988503 100644 --- a/app/controllers/jobs_controller.rb +++ b/app/controllers/jobs_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class JobsController < ApplicationController - before_action { authentication_check(permission: 'admin.scheduler') } + prepend_before_action { authentication_check(permission: 'admin.scheduler') } def index model_index_render(Job, params) diff --git a/app/controllers/karma_controller.rb b/app/controllers/karma_controller.rb index e87c7d367..0772ea030 100644 --- a/app/controllers/karma_controller.rb +++ b/app/controllers/karma_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class KarmaController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check def index render json: { diff --git a/app/controllers/links_controller.rb b/app/controllers/links_controller.rb index 28bbd51dc..35904dba5 100644 --- a/app/controllers/links_controller.rb +++ b/app/controllers/links_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class LinksController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /api/v1/links def index diff --git a/app/controllers/macros_controller.rb b/app/controllers/macros_controller.rb index 01ce8e0b7..97d055b6e 100644 --- a/app/controllers/macros_controller.rb +++ b/app/controllers/macros_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class MacrosController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check =begin diff --git a/app/controllers/monitoring_controller.rb b/app/controllers/monitoring_controller.rb index 1fa9c3bdc..cd03c671d 100644 --- a/app/controllers/monitoring_controller.rb +++ b/app/controllers/monitoring_controller.rb @@ -1,7 +1,8 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class MonitoringController < ApplicationController - before_action -> { authentication_check(permission: 'admin.monitoring') }, except: [:health_check, :status] + prepend_before_action -> { authentication_check(permission: 'admin.monitoring') }, except: [:health_check, :status] + skip_before_action :verify_csrf_token =begin diff --git a/app/controllers/network_controller.rb b/app/controllers/network_controller.rb index 0fcea7b42..5a7dd1a47 100644 --- a/app/controllers/network_controller.rb +++ b/app/controllers/network_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class NetworksController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /networks # GET /networks.json diff --git a/app/controllers/online_notifications_controller.rb b/app/controllers/online_notifications_controller.rb index 3e2a5f80f..f71969f77 100644 --- a/app/controllers/online_notifications_controller.rb +++ b/app/controllers/online_notifications_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class OnlineNotificationsController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check =begin diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 9259df98e..9ad221646 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class OrganizationsController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check =begin diff --git a/app/controllers/overviews_controller.rb b/app/controllers/overviews_controller.rb index bfff62ae7..65deb2d0f 100644 --- a/app/controllers/overviews_controller.rb +++ b/app/controllers/overviews_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class OverviewsController < ApplicationController - before_action { authentication_check(permission: 'admin.overview') } + prepend_before_action { authentication_check(permission: 'admin.overview') } =begin diff --git a/app/controllers/packages_controller.rb b/app/controllers/packages_controller.rb index 746ce23ae..1c5e0f38f 100644 --- a/app/controllers/packages_controller.rb +++ b/app/controllers/packages_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class PackagesController < ApplicationController - before_action { authentication_check(permission: 'admin.package') } + prepend_before_action { authentication_check(permission: 'admin.package') } # GET /api/v1/packages def index diff --git a/app/controllers/postmaster_filters_controller.rb b/app/controllers/postmaster_filters_controller.rb index 3986221b4..cb46f7c26 100644 --- a/app/controllers/postmaster_filters_controller.rb +++ b/app/controllers/postmaster_filters_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class PostmasterFiltersController < ApplicationController - before_action { authentication_check(permission: 'admin.channel_email') } + prepend_before_action { authentication_check(permission: 'admin.channel_email') } =begin diff --git a/app/controllers/proxy_controller.rb b/app/controllers/proxy_controller.rb index a93a2ad6b..1f43c7846 100644 --- a/app/controllers/proxy_controller.rb +++ b/app/controllers/proxy_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ProxyController < ApplicationController - before_action { authentication_check(permission: 'admin.system') } + prepend_before_action { authentication_check(permission: 'admin.system') } # POST /api/v1/proxy def test diff --git a/app/controllers/recent_view_controller.rb b/app/controllers/recent_view_controller.rb index 11e707626..9f54e2be4 100644 --- a/app/controllers/recent_view_controller.rb +++ b/app/controllers/recent_view_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class RecentViewController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check =begin diff --git a/app/controllers/report_profiles_controller.rb b/app/controllers/report_profiles_controller.rb index 48221a225..d39851568 100644 --- a/app/controllers/report_profiles_controller.rb +++ b/app/controllers/report_profiles_controller.rb @@ -1,5 +1,5 @@ class ReportProfilesController < ApplicationController - before_action { authentication_check(permission: 'admin.report_profile') } + prepend_before_action { authentication_check(permission: 'admin.report_profile') } =begin diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index d76b2471e..30b51e9ef 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -3,7 +3,7 @@ require 'tempfile' class ReportsController < ApplicationController - before_action { authentication_check(permission: 'report') } + prepend_before_action { authentication_check(permission: 'report') } # GET /api/reports/config def reporting_config diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 560d95195..1d6ca533b 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class RolesController < ApplicationController - before_action { authentication_check(permission: 'admin.role') } + prepend_before_action { authentication_check(permission: 'admin.role') } =begin diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 52717cfb1..affee2e97 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class SearchController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET|POST /api/v1/search # GET|POST /api/v1/search/:objects diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 885ca7de8..24ef01db3 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,6 +1,8 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class SessionsController < ApplicationController + prepend_before_action :authentication_check, only: [:switch_to_user, :list, :delete] + skip_before_action :verify_csrf_token, only: [:create, :show, :destroy, :create_omniauth, :create_sso] # "Create" a login, aka "log the user in" def create @@ -18,12 +20,11 @@ class SessionsController < ApplicationController raise Exceptions::NotAuthorized, 'Wrong Username and Password combination.' if !user # remember me - set session cookie to expire later - request.env['rack.session.options'][:expire_after] = if params[:remember_me] - 1.year - end - # both not needed to set :expire_after works fine - # request.env['rack.session.options'][:renew] = true - # reset_session + expire_after = nil + if params[:remember_me] + expire_after = 1.year + end + env['rack.session.options'][:expire_after] = expire_after # set session user current_user_set(user) @@ -114,11 +115,11 @@ class SessionsController < ApplicationController def destroy # Remove the user id from the session - @_current_user = session[:user_id] = nil + @_current_user = nil - # reset session cookie (reset :expire_after in case remember_me is active) - request.env['rack.session.options'][:expire_after] = -1.years - request.env['rack.session.options'][:renew] = true + # reset session + request.env['rack.session.options'][:expire_after] = nil + session.clear render json: {} end @@ -195,7 +196,6 @@ class SessionsController < ApplicationController # "switch" to user def switch_to_user - authentication_check permission_check('admin.session') # check user @@ -278,7 +278,6 @@ class SessionsController < ApplicationController end def list - authentication_check permission_check('admin.session') assets = {} sessions_clean = [] @@ -297,7 +296,6 @@ class SessionsController < ApplicationController end def delete - authentication_check permission_check('admin.session') SessionHelper.destroy(params[:id]) render json: {} diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index ba8a28b91..1a92a432a 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class SettingsController < ApplicationController - before_action { authentication_check(permission: 'admin.*') } + prepend_before_action { authentication_check(permission: 'admin.*') } # GET /settings def index diff --git a/app/controllers/signatures_controller.rb b/app/controllers/signatures_controller.rb index 88359225c..4cf1d770c 100644 --- a/app/controllers/signatures_controller.rb +++ b/app/controllers/signatures_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class SignaturesController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check =begin diff --git a/app/controllers/slas_controller.rb b/app/controllers/slas_controller.rb index 160281f22..99a2ceae0 100644 --- a/app/controllers/slas_controller.rb +++ b/app/controllers/slas_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class SlasController < ApplicationController - before_action { authentication_check(permission: 'admin.sla') } + prepend_before_action { authentication_check(permission: 'admin.sla') } =begin diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 3131e22c6..e9e66b0b7 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TagsController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /api/v1/tag_search?term=abc def search diff --git a/app/controllers/taskbar_controller.rb b/app/controllers/taskbar_controller.rb index 527db4e15..dd4cd7b61 100644 --- a/app/controllers/taskbar_controller.rb +++ b/app/controllers/taskbar_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TaskbarController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check def index current_user_tasks = Taskbar.where(user_id: current_user.id) diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index 5b3fef692..8f8abce87 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TemplatesController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check =begin diff --git a/app/controllers/text_modules_controller.rb b/app/controllers/text_modules_controller.rb index 46b038b2c..dada3340c 100644 --- a/app/controllers/text_modules_controller.rb +++ b/app/controllers/text_modules_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TextModulesController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check =begin diff --git a/app/controllers/ticket_articles_controller.rb b/app/controllers/ticket_articles_controller.rb index bff6d639e..37e967a62 100644 --- a/app/controllers/ticket_articles_controller.rb +++ b/app/controllers/ticket_articles_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TicketArticlesController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /articles def index diff --git a/app/controllers/ticket_overviews_controller.rb b/app/controllers/ticket_overviews_controller.rb index 8252c3685..6aa6ae1f1 100644 --- a/app/controllers/ticket_overviews_controller.rb +++ b/app/controllers/ticket_overviews_controller.rb @@ -3,7 +3,7 @@ require 'ticket/overviews' class TicketOverviewsController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /api/v1/ticket_overviews def show diff --git a/app/controllers/ticket_priorities_controller.rb b/app/controllers/ticket_priorities_controller.rb index 4d14af2df..7cc9381ab 100644 --- a/app/controllers/ticket_priorities_controller.rb +++ b/app/controllers/ticket_priorities_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TicketPrioritiesController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /ticket_priorities def index diff --git a/app/controllers/ticket_states_controller.rb b/app/controllers/ticket_states_controller.rb index fa66a8376..ca56750ba 100644 --- a/app/controllers/ticket_states_controller.rb +++ b/app/controllers/ticket_states_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TicketStatesController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /ticket_states def index diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index e7e1b60ce..cda95e56e 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TicketsController < ApplicationController - before_action :authentication_check + prepend_before_action :authentication_check # GET /api/v1/tickets def index diff --git a/app/controllers/time_accountings_controller.rb b/app/controllers/time_accountings_controller.rb index 58dc0bd36..40ce3c1e8 100644 --- a/app/controllers/time_accountings_controller.rb +++ b/app/controllers/time_accountings_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TimeAccountingsController < ApplicationController - before_action { authentication_check(permission: 'admin.time_accounting') } + prepend_before_action { authentication_check(permission: 'admin.time_accounting') } def by_ticket diff --git a/app/controllers/translations_controller.rb b/app/controllers/translations_controller.rb index d58353a54..7a295d4a6 100644 --- a/app/controllers/translations_controller.rb +++ b/app/controllers/translations_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TranslationsController < ApplicationController - before_action :authentication_check, except: [:lang] + prepend_before_action :authentication_check, except: [:lang] # GET /translations/lang/:locale def lang diff --git a/app/controllers/triggers_controller.rb b/app/controllers/triggers_controller.rb index a353f7b03..f87b252c5 100644 --- a/app/controllers/triggers_controller.rb +++ b/app/controllers/triggers_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class TriggersController < ApplicationController - before_action { authentication_check(permission: 'admin.trigger') } + prepend_before_action { authentication_check(permission: 'admin.trigger') } def index model_index_render(Trigger, params) diff --git a/app/controllers/user_access_token_controller.rb b/app/controllers/user_access_token_controller.rb index 9669f06d0..7a4a27dc8 100644 --- a/app/controllers/user_access_token_controller.rb +++ b/app/controllers/user_access_token_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class UserAccessTokenController < ApplicationController - before_action { authentication_check(permission: 'user_preferences.access_token') } + prepend_before_action { authentication_check(permission: 'user_preferences.access_token') } def index tokens = Token.where(action: 'api', persistent: true, user_id: current_user.id).order('updated_at DESC, label ASC') diff --git a/app/controllers/user_devices_controller.rb b/app/controllers/user_devices_controller.rb index 721fded97..10f9a13f3 100644 --- a/app/controllers/user_devices_controller.rb +++ b/app/controllers/user_devices_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class UserDevicesController < ApplicationController - before_action { authentication_check(permission: 'user_preferences.device') } + prepend_before_action { authentication_check(permission: 'user_preferences.device') } def index devices = UserDevice.where(user_id: current_user.id).order('updated_at DESC, name ASC') diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a94b00eca..8ef94d4a3 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,7 +1,8 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class UsersController < ApplicationController - before_action :authentication_check, except: [:create, :password_reset_send, :password_reset_verify, :image] + prepend_before_action :authentication_check, except: [:create, :password_reset_send, :password_reset_verify, :image] + prepend_before_action :authentication_check_only, only: [:create] # @path [GET] /users # @@ -105,10 +106,6 @@ class UsersController < ApplicationController # @response_message 200 [User] Created User record. # @response_message 401 Invalid session. def create - - # in case of authentication, set current_user to access later - authentication_check_only({}) - clean_params = User.association_name_to_id_convert(params) clean_params = User.param_cleanup(clean_params, true) user = User.new(clean_params) diff --git a/app/controllers/version_controller.rb b/app/controllers/version_controller.rb index 221715f1e..639a4e72d 100644 --- a/app/controllers/version_controller.rb +++ b/app/controllers/version_controller.rb @@ -1,7 +1,7 @@ # Copyright (C) 2012-2017 Zammad Foundation, http://zammad-foundation.org/ class VersionController < ApplicationController - before_action { authentication_check(permission: 'admin.version') } + prepend_before_action { authentication_check(permission: 'admin.version') } # GET /api/v1/version def index diff --git a/app/models/role.rb b/app/models/role.rb index dfaba9e61..332298169 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -93,7 +93,7 @@ get all roles with permission "admin.session" or "ticket.agent" returns - [user1, user2, ...] + [role1, role2, ...] =end diff --git a/db/migrate/20170214000001_reload_online_browser_after_cors_csrf_changes.rb b/db/migrate/20170214000001_reload_online_browser_after_cors_csrf_changes.rb new file mode 100644 index 000000000..bf33fc4ab --- /dev/null +++ b/db/migrate/20170214000001_reload_online_browser_after_cors_csrf_changes.rb @@ -0,0 +1,8 @@ +class ReloadOnlineBrowserAfterCorsCsrfChanges < ActiveRecord::Migration + def up + + # return if it's a new setup + return if !Setting.find_by(name: 'system_init_done') + AppVersion.set(true, 'app_version') + end +end diff --git a/test/browser/auth_test.rb b/test/browser/auth_test.rb index c8e0340ac..ee09c79cf 100644 --- a/test/browser/auth_test.rb +++ b/test/browser/auth_test.rb @@ -77,9 +77,11 @@ class AuthTest < TestCase logout() # verify session cookie + sleep 2 cookie( name: '^_zammad.+?', - should_not_exist: true, + value: '.+?', + expires: '', ) end diff --git a/test/controllers/api_auth_controller_test.rb b/test/controllers/api_auth_controller_test.rb index e7d274673..edf959925 100644 --- a/test/controllers/api_auth_controller_test.rb +++ b/test/controllers/api_auth_controller_test.rb @@ -57,6 +57,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_password_access', false) get '/api/v1/sessions', {}, @headers.merge('Authorization' => admin_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('API password access disabled!', result['error']) @@ -64,6 +65,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_password_access', true) get '/api/v1/sessions', {}, @headers.merge('Authorization' => admin_credentials) assert_response(200) + assert_equal('*', @response.header['Access-Control-Allow-Origin']) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert(result) @@ -76,6 +78,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_password_access', false) get '/api/v1/tickets', {}, @headers.merge('Authorization' => agent_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('API password access disabled!', result['error']) @@ -83,6 +86,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_password_access', true) get '/api/v1/tickets', {}, @headers.merge('Authorization' => agent_credentials) assert_response(200) + assert_equal('*', @response.header['Access-Control-Allow-Origin']) result = JSON.parse(@response.body) assert_equal(Array, result.class) assert(result) @@ -95,6 +99,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_password_access', false) get '/api/v1/tickets', {}, @headers.merge('Authorization' => customer_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('API password access disabled!', result['error']) @@ -102,6 +107,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_password_access', true) get '/api/v1/tickets', {}, @headers.merge('Authorization' => customer_credentials) assert_response(200) + assert_equal('*', @response.header['Access-Control-Allow-Origin']) result = JSON.parse(@response.body) assert_equal(Array, result.class) assert(result) @@ -122,6 +128,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_token_access', false) get '/api/v1/sessions', {}, @headers.merge('Authorization' => admin_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('API token access disabled!', result['error']) @@ -129,6 +136,8 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_token_access', true) get '/api/v1/sessions', {}, @headers.merge('Authorization' => admin_credentials) assert_response(200) + assert_equal('*', @response.header['Access-Control-Allow-Origin']) + result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert(result) @@ -207,6 +216,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_token_access', false) get '/api/v1/tickets', {}, @headers.merge('Authorization' => agent_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('API token access disabled!', result['error']) @@ -214,6 +224,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_token_access', true) get '/api/v1/tickets', {}, @headers.merge('Authorization' => agent_credentials) assert_response(200) + assert_equal('*', @response.header['Access-Control-Allow-Origin']) result = JSON.parse(@response.body) assert_equal(Array, result.class) assert(result) @@ -231,12 +242,14 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_token_access', false) get '/api/v1/tickets', {}, @headers.merge('Authorization' => customer_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('API token access disabled!', result['error']) Setting.set('api_token_access', true) get '/api/v1/tickets', {}, @headers.merge('Authorization' => customer_credentials) + assert_equal('*', @response.header['Access-Control-Allow-Origin']) assert_response(200) result = JSON.parse(@response.body) assert_equal(Array, result.class) @@ -258,6 +271,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_token_access', false) get '/api/v1/sessions', {}, @headers.merge('Authorization' => admin_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('API token access disabled!', result['error']) @@ -265,6 +279,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest Setting.set('api_token_access', true) get '/api/v1/sessions', {}, @headers.merge('Authorization' => admin_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('User is inactive!', result['error']) @@ -284,6 +299,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest get '/api/v1/tickets', {}, @headers.merge('Authorization' => admin_credentials) assert_response(401) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) result = JSON.parse(@response.body) assert_equal(Hash, result.class) assert_equal('Not authorized (token expired)!', result['error']) @@ -306,6 +322,7 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest get '/api/v1/tickets', {}, @headers.merge('Authorization' => admin_credentials) assert_response(200) + assert_equal('*', @response.header['Access-Control-Allow-Origin']) result = JSON.parse(@response.body) assert_equal(Array, result.class) assert(result) @@ -314,4 +331,18 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest assert_in_delta(admin_token.last_used_at, Time.zone.now, 1.second) end + test 'session auth - admin' do + + post '/api/v1/signin', { username: 'api-admin@example.com', password: 'adminpw', fingerprint: '123456789' } + assert_not(@response.header.key?('Access-Control-Allow-Origin')) + assert_response(201) + + get '/api/v1/sessions', {} + assert_response(200) + assert_not(@response.header.key?('Access-Control-Allow-Origin')) + result = JSON.parse(@response.body) + assert_equal(Hash, result.class) + assert(result) + end + end diff --git a/test/controllers/user_organization_controller_test.rb b/test/controllers/user_organization_controller_test.rb index d7dbc3dbe..0be068ece 100644 --- a/test/controllers/user_organization_controller_test.rb +++ b/test/controllers/user_organization_controller_test.rb @@ -75,20 +75,34 @@ class UserOrganizationControllerTest < ActionDispatch::IntegrationTest test 'user create tests - no user' do + post '/api/v1/signshow', {}, @headers + # create user with disabled feature Setting.set('user_create_account', false) - params = { email: 'some_new_customer@example.com' } + token = @response.headers['CSRF-TOKEN'] + + # token based on form + params = { email: 'some_new_customer@example.com', authenticity_token: token } post '/api/v1/users', params.to_json, @headers assert_response(422) result = JSON.parse(@response.body) assert(result['error']) assert_equal('Feature not enabled!', result['error']) + # token based on headers + headers = @headers.merge('X-CSRF-Token' => token) + params = { email: 'some_new_customer@example.com' } + post '/api/v1/users', params.to_json, headers + assert_response(422) + result = JSON.parse(@response.body) + assert(result['error']) + assert_equal('Feature not enabled!', result['error']) + Setting.set('user_create_account', true) # no signup param with enabled feature params = { email: 'some_new_customer@example.com' } - post '/api/v1/users', params.to_json, @headers + post '/api/v1/users', params.to_json, headers assert_response(422) result = JSON.parse(@response.body) assert(result['error']) @@ -96,7 +110,7 @@ class UserOrganizationControllerTest < ActionDispatch::IntegrationTest # already existing user with enabled feature params = { email: 'rest-customer1@example.com', signup: true } - post '/api/v1/users', params.to_json, @headers + post '/api/v1/users', params.to_json, headers assert_response(422) result = JSON.parse(@response.body) assert(result['error']) @@ -104,7 +118,7 @@ class UserOrganizationControllerTest < ActionDispatch::IntegrationTest # create user with enabled feature (take customer role) params = { firstname: 'Me First', lastname: 'Me Last', email: 'new_here@example.com', signup: true } - post '/api/v1/users', params.to_json, @headers + post '/api/v1/users', params.to_json, headers assert_response(201) result = JSON.parse(@response.body) assert(result) @@ -121,7 +135,7 @@ class UserOrganizationControllerTest < ActionDispatch::IntegrationTest # create user with admin role (not allowed for signup, take customer role) role = Role.lookup(name: 'Admin') params = { firstname: 'Admin First', lastname: 'Admin Last', email: 'new_admin@example.com', role_ids: [ role.id ], signup: true } - post '/api/v1/users', params.to_json, @headers + post '/api/v1/users', params.to_json, headers assert_response(201) result = JSON.parse(@response.body) assert(result) @@ -133,7 +147,7 @@ class UserOrganizationControllerTest < ActionDispatch::IntegrationTest # create user with agent role (not allowed for signup, take customer role) role = Role.lookup(name: 'Agent') params = { firstname: 'Agent First', lastname: 'Agent Last', email: 'new_agent@example.com', role_ids: [ role.id ], signup: true } - post '/api/v1/users', params.to_json, @headers + post '/api/v1/users', params.to_json, headers assert_response(201) result = JSON.parse(@response.body) assert(result) @@ -143,13 +157,13 @@ class UserOrganizationControllerTest < ActionDispatch::IntegrationTest assert(user.role?('Customer')) # no user (because of no session) - get '/api/v1/users', {}, @headers + get '/api/v1/users', {}, headers assert_response(401) result = JSON.parse(@response.body) assert_equal('authentication failed', result['error']) # me - get '/api/v1/users/me', {}, @headers + get '/api/v1/users/me', {}, headers assert_response(401) result = JSON.parse(@response.body) assert_equal('authentication failed', result['error'])