diff options
author | Stefan Wintermeyer <stefan.wintermeyer@amooma.de> | 2012-12-17 12:01:45 +0100 |
---|---|---|
committer | Stefan Wintermeyer <stefan.wintermeyer@amooma.de> | 2012-12-17 12:01:45 +0100 |
commit | b80bd744ad873f6fc43018bc4bfb90677de167bd (patch) | |
tree | 072c4b0e33d442528555b82c415f5e7a1712b2b0 /app/controllers | |
parent | 3e706c2025ecc5523e81ad649639ef2ff75e7bac (diff) |
Start of GS5.
Diffstat (limited to 'app/controllers')
48 files changed, 6524 insertions, 0 deletions
diff --git a/app/controllers/access_authorizations_controller.rb b/app/controllers/access_authorizations_controller.rb new file mode 100644 index 0000000..54365e7 --- /dev/null +++ b/app/controllers/access_authorizations_controller.rb @@ -0,0 +1,68 @@ +class AccessAuthorizationsController < ApplicationController + load_and_authorize_resource :callthrough + load_and_authorize_resource :access_authorization, :through => [:callthrough] + + before_filter :set_parent_and_path_methods + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @access_authorization = @parent.access_authorizations.build + @access_authorization.name = generate_a_new_name(@parent, @access_authorization) + @access_authorization.phone_numbers.build + @access_authorization.login = random_pin + random_pin + @access_authorization.pin = random_pin + end + + def create + @access_authorization = @parent.access_authorizations.build(params[:access_authorization]) + if @access_authorization.save + redirect_to @show_path_method.(@parent, @access_authorization), :notice => t('access_authorizations.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @access_authorization.update_attributes(params[:access_authorization]) + redirect_to @show_path_method.(@parent, @access_authorization), :notice => t('access_authorizations.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @access_authorization.destroy + redirect_to @index_path_method.(@parent), :notice => t('access_authorizations.controller.successfuly_destroyed') + end + + private + + def set_parent_and_path_methods + @parent = @callthrough + @show_path_method = method( :"#{@parent.class.name.underscore}_access_authorization_path" ) + @index_path_method = method( :"#{@parent.class.name.underscore}_access_authorizations_path" ) + @new_path_method = method( :"new_#{@parent.class.name.underscore}_access_authorization_path" ) + @edit_path_method = method( :"edit_#{@parent.class.name.underscore}_access_authorization_path" ) + end + + def spread_breadcrumbs + if @callthrough + add_breadcrumb t("#{@parent.class.name.underscore.pluralize}.index.page_title"), tenant_callthroughs_path(@callthrough.tenant) + add_breadcrumb @callthrough, tenant_callthrough_path(@callthrough.tenant, @callthrough) + add_breadcrumb t("access_authorizations.index.page_title"), callthrough_access_authorizations_path(@callthrough) + if @access_authorization && !@access_authorization.new_record? + add_breadcrumb @access_authorization, callthrough_access_authorization_path(@callthrough, @access_authorization) + end + end + end + +end diff --git a/app/controllers/acd_agents_controller.rb b/app/controllers/acd_agents_controller.rb new file mode 100644 index 0000000..1d119b3 --- /dev/null +++ b/app/controllers/acd_agents_controller.rb @@ -0,0 +1,73 @@ +class AcdAgentsController < ApplicationController + load_and_authorize_resource :automatic_call_distributor + load_and_authorize_resource :acd_agent, :through => [:automatic_call_distributor] + + before_filter :spread_breadcrumbs + + def index + if params[:active] + if params[:active].downcase == 'true' + @acd_agents = @acd_agents.where(:active => true) + elsif params[:active].downcase == 'false' + @acd_agents = @acd_agents.where(:active => false) + end + end + end + + def show + @acd_agent = AcdAgent.find(params[:id]) + end + + def new + @acd_agent = @automatic_call_distributor.acd_agents.build + i = @automatic_call_distributor.acd_agents.count + loop do + i += 1 + break unless @automatic_call_distributor.acd_agents.where(:name => "#{t('acd_agents.name')} #{i}").count > 0 + end + @acd_agent.name = "#{t('acd_agents.name')} #{i}" + @acd_agent.status = 'active' + @acd_agent.calls_answered = 0 + end + + def create + @acd_agent = @automatic_call_distributor.acd_agents.build(params[:acd_agent]) + if @acd_agent.save + redirect_to automatic_call_distributor_acd_agent_path(@automatic_call_distributor, @acd_agent), :notice => t('acd_agents.controller.successfuly_created') + else + render :new + end + end + + def edit + @acd_agent = AcdAgent.find(params[:id]) + end + + def update + @acd_agent = AcdAgent.find(params[:id]) + if @acd_agent.update_attributes(params[:acd_agent]) + redirect_to automatic_call_distributor_acd_agent_path(@automatic_call_distributor, @acd_agent), :notice => t('acd_agents.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @acd_agent = AcdAgent.find(params[:id]) + @acd_agent.destroy + redirect_to automatic_call_distributor_acd_agents_path(@automatic_call_distributor), :notice => t('acd_agents.controller.successfuly_destroyed') + end + + def spread_breadcrumbs + if @automatic_call_distributor.automatic_call_distributorable.class == User + add_breadcrumb t("#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore.pluralize}.index.page_title"), method( :"tenant_#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore.pluralize}_path" ).(@automatic_call_distributor.tenant) + add_breadcrumb @automatic_call_distributor.automatic_call_distributorable, method( :"tenant_#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore}_path" ).(@automatic_call_distributor.tenant, @automatic_call_distributor.automatic_call_distributorable) + end + add_breadcrumb t("automatic_call_distributors.index.page_title"), method( :"#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore}_automatic_call_distributors_path" ).(@automatic_call_distributor.automatic_call_distributorable) + add_breadcrumb @automatic_call_distributor, method( :"#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore}_automatic_call_distributor_path" ).(@automatic_call_distributor.automatic_call_distributorable, @automatic_call_distributor) + add_breadcrumb t("acd_agents.index.page_title"), automatic_call_distributor_acd_agents_path(@automatic_call_distributor) + if @acd_agent && !@acd_agent.new_record? + add_breadcrumb @acd_agent, automatic_call_distributor_acd_agent_path(@automatic_call_distributor, @acd_agent) + end + end +end diff --git a/app/controllers/acd_callers_controller.rb b/app/controllers/acd_callers_controller.rb new file mode 100644 index 0000000..ab58064 --- /dev/null +++ b/app/controllers/acd_callers_controller.rb @@ -0,0 +1,41 @@ +class AcdCallersController < ApplicationController + def index + @acd_callers = AcdCaller.all + end + + def show + @acd_caller = AcdCaller.find(params[:id]) + end + + def new + @acd_caller = AcdCaller.new + end + + def create + @acd_caller = AcdCaller.new(params[:acd_caller]) + if @acd_caller.save + redirect_to @acd_caller, :notice => t('acd_callers.controller.successfuly_created') + else + render :new + end + end + + def edit + @acd_caller = AcdCaller.find(params[:id]) + end + + def update + @acd_caller = AcdCaller.find(params[:id]) + if @acd_caller.update_attributes(params[:acd_caller]) + redirect_to @acd_caller, :notice => t('acd_callers.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @acd_caller = AcdCaller.find(params[:id]) + @acd_caller.destroy + redirect_to acd_callers_url, :notice => t('acd_callers.controller.successfuly_destroyed') + end +end diff --git a/app/controllers/addresses_controller.rb b/app/controllers/addresses_controller.rb new file mode 100644 index 0000000..a70b1f4 --- /dev/null +++ b/app/controllers/addresses_controller.rb @@ -0,0 +1,41 @@ +class AddressesController < ApplicationController + def index + @addresses = Address.all + end + + def show + @address = Address.find(params[:id]) + end + + def new + @address = Address.new + end + + def create + @address = Address.new(params[:address]) + if @address.save + redirect_to @address, :notice => t('addresses.controller.successfuly_created') + else + render :new + end + end + + def edit + @address = Address.find(params[:id]) + end + + def update + @address = Address.find(params[:id]) + if @address.update_attributes(params[:address]) + redirect_to @address, :notice => t('addresses.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @address = Address.find(params[:id]) + @address.destroy + redirect_to addresses_url, :notice => t('addresses.controller.successfuly_destroyed') + end +end diff --git a/app/controllers/api/rows_controller.rb b/app/controllers/api/rows_controller.rb new file mode 100644 index 0000000..6e815eb --- /dev/null +++ b/app/controllers/api/rows_controller.rb @@ -0,0 +1,91 @@ +class Api::RowsController < ApplicationController + before_filter :check_remote_ip_address_whitelist + + def index + @rows = Api::Row.all + + respond_to do |format| + format.xml { render xml: @rows } + end + end + + def show + if params[:user_name] + @row = Api::Row.find_by_user_name(params[:user_name]) + else + @row = Api::Row.find(params[:id]) + end + + respond_to do |format| + format.xml { render xml: @row } + end + end + + def new + @row = Api::Row.new + + respond_to do |format| + format.xml { render xml: @row } + end + end + + def edit + if params[:user_name] + @row = Api::Row.find_by_user_name(params[:user_name]) + else + @row = Api::Row.find(params[:id]) + end + end + + def create + @row = Api::Row.new(params[:row]) + + respond_to do |format| + if @row.save + @row.create_a_new_gemeinschaft_user + + format.xml { render xml: @row, status: :created, location: @row } + else + format.xml { render xml: @row.errors, status: :unprocessable_entity } + end + end + end + + def update + if params[:user_name] + @row = Api::Row.find_by_user_name(params[:user_name]) + else + @row = Api::Row.find(params[:id]) + end + + respond_to do |format| + if @row.update_attributes(params[:row]) + @row.update_user_data + format.xml { head :no_content } + else + format.xml { render xml: @row.errors, status: :unprocessable_entity } + end + end + end + + def destroy + if params[:user_name] + @row = Api::Row.find_by_user_name(params[:user_name]) + else + @row = Api::Row.find(params[:id]) + end + @row.destroy + + respond_to do |format| + format.xml { head :no_content } + end + end + + private + + def check_remote_ip_address_whitelist + if !(REMOTE_IP_ADDRESS_WHITELIST.empty? or REMOTE_IP_ADDRESS_WHITELIST.include?(ENV['REMOTE_ADDR'])) + redirect_to root_url + end + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..c675f5c --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,161 @@ +class ApplicationController < ActionController::Base + + protect_from_forgery + + before_filter :set_locale + + before_filter :go_to_setup_if_new_installation + before_filter :home_breadcrumb + + helper_method :current_user + + helper_method :guess_local_ip_address + helper_method :guess_local_host + + helper_method :'have_https?' + + helper_method :random_pin + + + #TODO Add check_authorization. See + # https://github.com/ryanb/cancan + # https://github.com/ryanb/cancan/wiki/Ensure-Authorization + # and Gemeinschaft 4 + + # Generate a new name for an Object + # + def generate_a_new_name(parent, child = nil) + if child + i = parent.send(child.class.name.underscore.pluralize).count + loop do + i += 1 + if I18n.t("#{child.class.name.underscore.pluralize}.new_name_scaffold").include?('translation missing') + @guess_a_new_name = I18n.t(child.class.name.underscore.pluralize + '.name') + " #{i}" + else + @guess_a_new_name = I18n.t("#{child.class.name.underscore.pluralize}.new_name_scaffold", :counter => i.to_s) + end + break unless parent.send(child.class.name.underscore.pluralize).where(:name => "#{@guess_a_new_name}").count > 0 + end + else + i = parent.class.count + loop do + i += 1 + if I18n.t("#{parent.class.name.underscore.pluralize}.new_name_scaffold").include?('translation missing') + @guess_a_new_name = I18n.t(parent.class.name.underscore.pluralize + '.name') + " #{i}" + else + @guess_a_new_name = I18n.t("#{parent.class.name.underscore.pluralize}.new_name_scaffold", :counter => i.to_s) + end + break unless parent.class.where(:name => "#{@guess_a_new_name}").count > 0 + end + end + return @guess_a_new_name + end + + # Generate a new random PIN + # + def random_pin + if MINIMUM_PIN_LENGTH > 0 + (1..MINIMUM_PIN_LENGTH).map{|i| (0 .. 9).to_a.sample}.join + end + end + + # return the IP address (preferred) or hostname at which the + # current request arrived + def server_host + return ( + request.env['SERVER_ADDR'] || + request.env['SERVER_NAME'] || + request.env['HTTP_HOST'] + ) + end + + def have_https? + return Connectivity::port_open?( server_host(), 443 ) + end + + + def guess_local_ip_address + ret = nil + begin + ipsocket_addr_info = UDPSocket.open {|s| s.connect("255.255.255.254", 1); s.addr(false) } + ret = ipsocket_addr_info.last if ipsocket_addr_info + rescue + end + return ret + end + + def guess_local_host + ret = guess_local_ip_address() + if ! ret + begin + if request + ret = request.env['SERVER_NAME'] + end + rescue + end + end + if ret && [ + '', + 'localhost', + '127.0.0.1', + '0.0.0.0', + ].include?(ret) + ret = nil + end + return ret + end + + rescue_from CanCan::AccessDenied do |exception| + if @current_user + redirect_to root_url, :alert => 'Access denied! Please ask your admin to grant you the necessary rights.' + else + if Tenant.count == 0 && User.count == 0 + # This is a brand new system. We need to run a setup first. + redirect_to wizards_new_initial_setup_path + else + # You need to login first. + redirect_to log_in_path, :alert => 'Access denied! You need to login first.' + end + end + end + + private + + def current_user + begin + @current_user ||= User.find(session[:user_id]) if session[:user_id] + rescue ActiveRecord::RecordNotFound + session[:user_id] = nil + end + @current_user + end + + def go_to_setup_if_new_installation + if Rails.env != 'test' + if GemeinschaftSetup.all.count == 0 + redirect_to new_gemeinschaft_setup_path + end + end + end + + def home_breadcrumb + if current_user + if current_user && Tenant.find(current_user.current_tenant_id) + add_breadcrumb( current_user.current_tenant, tenant_path(current_user.current_tenant) ) + else + add_breadcrumb I18n.t('pages.controller.index.name'), :root_path + end + end + end + + def set_locale + if current_user && Language.find(current_user.language_id) + I18n.locale = current_user.language.code.downcase + else + logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}" + I18n.locale = request.compatible_language_from(Language.all.map{|x| x.code}) + end + logger.debug "* Locale set to '#{I18n.locale}'" + end + +end diff --git a/app/controllers/automatic_call_distributors_controller.rb b/app/controllers/automatic_call_distributors_controller.rb new file mode 100644 index 0000000..cc0c7e6 --- /dev/null +++ b/app/controllers/automatic_call_distributors_controller.rb @@ -0,0 +1,100 @@ +class AutomaticCallDistributorsController < ApplicationController + DEFAULT_STRATEGY = 'round_robin' + DEFAULT_MAX_CALLERS = 50 + DEFAULT_AGENT_TIMEOUT = 20 + DEFAULT_RETRY_TIMEOUT = 10 + DEFAULT_JOIN = 'agents_active' + DEFAULT_LEAVE = 'no_agents_active' + + load_resource :user + load_resource :tenant + load_and_authorize_resource :automatic_call_distributor, :through => [:user, :tenant ] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + @automatic_call_distributors = AutomaticCallDistributor.all + end + + def show + @automatic_call_distributor = AutomaticCallDistributor.find(params[:id]) + end + + def new + i = @parent.automatic_call_distributors.count + loop do + i += 1 + break unless @parent.automatic_call_distributors.where(:name => "#{t('automatic_call_distributors.name')} #{i}").count > 0 + end + @strategies = AutomaticCallDistributor::STRATEGIES.collect {|r| [ t("automatic_call_distributors.strategies.#{r.to_s}"), r.to_s ] } + @join_on = AutomaticCallDistributor::JOIN_ON.collect {|r| [ t("automatic_call_distributors.join_on.#{r.to_s}"), r.to_s ] } + @leave_on = AutomaticCallDistributor::LEAVE_ON.collect {|r| [ t("automatic_call_distributors.leave_on.#{r.to_s}"), r.to_s ] } + @automatic_call_distributor = @parent.automatic_call_distributors.build( + :name => "#{t('automatic_call_distributors.name')} #{i}", + :strategy => DEFAULT_STRATEGY, + :max_callers => DEFAULT_MAX_CALLERS, + :retry_timeout => DEFAULT_RETRY_TIMEOUT, + :agent_timeout => DEFAULT_AGENT_TIMEOUT, + :join => DEFAULT_JOIN, + :leave => DEFAULT_LEAVE, + ) + + end + + def create + @automatic_call_distributor = @parent.automatic_call_distributors.build(params[:automatic_call_distributor]) + if @automatic_call_distributor.save + m = method( :"#{@parent.class.name.underscore}_automatic_call_distributor_path" ) + redirect_to m.( @parent, @automatic_call_distributor ), :notice => t('automatic_call_distributors.controller.successfuly_created', :resource => @parent) + else + render :new + end + end + + def edit + @strategies = AutomaticCallDistributor::STRATEGIES.collect {|r| [ t("automatic_call_distributors.strategies.#{r.to_s}"), r.to_s ] } + @join_on = AutomaticCallDistributor::JOIN_ON.collect {|r| [ t("automatic_call_distributors.join_on.#{r.to_s}"), r.to_s ] } + @leave_on = AutomaticCallDistributor::LEAVE_ON.collect {|r| [ t("automatic_call_distributors.leave_on.#{r.to_s}"), r.to_s ] } + @automatic_call_distributor = AutomaticCallDistributor.find(params[:id]) + end + + def update + if @automatic_call_distributor.update_attributes(params[:automatic_call_distributor]) + m = method( :"#{@parent.class.name.underscore}_automatic_call_distributor_path" ) + redirect_to m.( @parent, @automatic_call_distributor ), :notice => t('automatic_call_distributors.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @automatic_call_distributor = AutomaticCallDistributor.find(params[:id]) + @automatic_call_distributor.destroy + m = method( :"#{@parent.class.name.underscore}_automatic_call_distributors_url" ) + redirect_to m.( @parent ), :notice => t('automatic_call_distributors.controller.successfuly_destroyed') + end + + private + def set_and_authorize_parent + @parent = @user || @tenant + authorize! :read, @parent + end + + def spread_breadcrumbs + if @user + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t("automatic_call_distributors.index.page_title"), user_automatic_call_distributors_path(@user) + if @automatic_call_distributor && !@automatic_call_distributor.new_record? + add_breadcrumb @automatic_call_distributor, user_automatic_call_distributor_path(@user, @automatic_call_distributor) + end + end + if @tenant + add_breadcrumb t("automatic_call_distributors.index.page_title"), tenant_automatic_call_distributors_path(@tenant) + if @automatic_call_distributor && !@automatic_call_distributor.new_record? + add_breadcrumb @automatic_call_distributor, tenant_automatic_call_distributor_path(@tenant, @automatic_call_distributor) + end + end + end +end diff --git a/app/controllers/call_forwards_controller.rb b/app/controllers/call_forwards_controller.rb new file mode 100644 index 0000000..5321b35 --- /dev/null +++ b/app/controllers/call_forwards_controller.rb @@ -0,0 +1,127 @@ +class CallForwardsController < ApplicationController + load_and_authorize_resource :phone_number + load_and_authorize_resource :call_forward, :through => [:phone_number] + + before_filter :spread_breadcrumbs + + class CallForwardingDestination + attr_accessor :id, :label + + def to_s + return label + end + end + + + def index + end + + def show + end + + def new + @call_forward = @phone_number.call_forwards.build + @call_forward.depth = DEFAULT_CALL_FORWARD_DEPTH + @call_forward.active = true + @call_forwarding_destinations = call_forwarding_destination_types() + @call_forward.destination = CALLFORWARD_DESTINATION_DEFAULT.to_s if defined?(CALLFORWARD_DESTINATION_DEFAULT) + + @available_call_forward_cases = [] + CallForwardCase.all.each do |available_call_forward_case| + if GuiFunction.display?("call_forward_case_#{available_call_forward_case.value}_field_in_call_forward_form", @current_user) + @available_call_forward_cases << available_call_forward_case + end + end + + if @phone_number.call_forwards.where( + :call_forward_case_id => CallForwardCase.find_by_value('noanswer').id, + :active => true + ).count == 0 + @call_forward.call_forward_case_id = CallForwardCase.find_by_value('noanswer').id + @call_forward.timeout = 45 + end + end + + def create + @call_forward = @phone_number.call_forwards.build( params[:call_forward] ) + + if @call_forward.save + redirect_to phone_number_call_forward_path( @phone_number, @call_forward ), :notice => t('call_forwards.controller.successfuly_created') + else + @available_call_forward_cases = CallForwardCase.all + render :new + end + end + + def edit + @available_call_forward_cases = CallForwardCase.all + @call_forwarding_destinations = call_forwarding_destination_types() + end + + def update + @available_call_forward_cases = CallForwardCase.all + if @call_forward.update_attributes(params[:call_forward]) + redirect_to phone_number_call_forward_path( @phone_number, @call_forward ), :notice => t('call_forwards.controller.successfuly_updated') + else + @call_forwarding_destinations = call_forwarding_destination_types() + render :edit + end + end + + def destroy + @call_forward.destroy + redirect_to phone_number_call_forwards_path( @phone_number ), :notice => t('call_forwards.controller.successfuly_destroyed') + end + + private + def spread_breadcrumbs + if @phone_number && @phone_number.phone_numberable_type == 'SipAccount' + @sip_account = @phone_number.phone_numberable + if @sip_account.sip_accountable_type == 'User' + @user = @phone_number.phone_numberable.sip_accountable + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_users_path(@user.current_tenant, @user) + add_breadcrumb t("sip_accounts.index.page_title"), user_sip_accounts_path(@user) + add_breadcrumb @sip_account, user_sip_account_path(@user, @sip_account) + end + if @sip_account.sip_accountable_type == 'Tenant' + @tenant = @sip_account.sip_accountable + add_breadcrumb t("sip_accounts.index.page_title"), tenant_sip_accounts_path(@tenant) + add_breadcrumb @sip_account, tenant_sip_account_path(@tenant, @sip_account) + end + add_breadcrumb t("phone_numbers.index.page_title"), sip_account_phone_numbers_path(@sip_account) + add_breadcrumb @phone_number, sip_account_phone_number_path(@sip_account, @phone_number) + add_breadcrumb t("call_forwards.index.page_title"), phone_number_call_forwards_path(@phone_number) + if @call_forward && !@call_forward.new_record? + add_breadcrumb @call_forward, phone_number_call_forward_path(@phone_number, @call_forward) + end + end + end + + def call_forwarding_destination_types + + phone_number_destination = CallForwardingDestination.new() + phone_number_destination.id = ':PhoneNumber' + phone_number_destination.label = 'Phone Number' + voice_mail_destination = CallForwardingDestination.new() + voice_mail_destination.id = ':Voicemail' + voice_mail_destination.label = 'Voice Mail' + + call_forwarding_destinations = [ + phone_number_destination, + voice_mail_destination, + ] + + if GuiFunction.display?('huntgroup_in_destination_field_in_call_forward_form', @current_user) + HuntGroup.all.each do |hunt_group| + hunt_group_destination = CallForwardingDestination.new() + hunt_group_destination.id = "#{hunt_group.id}:HuntGroup" + hunt_group_destination.label = "HuntGroup: #{hunt_group.to_s}" + call_forwarding_destinations.push(hunt_group_destination) + end + end + + return call_forwarding_destinations + end + +end diff --git a/app/controllers/call_histories_controller.rb b/app/controllers/call_histories_controller.rb new file mode 100644 index 0000000..f956f88 --- /dev/null +++ b/app/controllers/call_histories_controller.rb @@ -0,0 +1,100 @@ +class CallHistoriesController < ApplicationController + + load_resource :sip_account + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + before_filter { |controller| + if ! params[:type].blank? then + @type = params[:type].to_s + end + + if ! params[:page].blank? then + @pagination_page_number = params[:page].to_i + end + } + + def index + hunt_group_member_ids = PhoneNumber.where(:phone_numberable_type => 'HuntGroupMember', :number => @sip_account.phone_numbers.map {|a| a.number}).map {|a| a.phone_numberable_id} + hunt_group_ids = HuntGroupMember.where(:id => hunt_group_member_ids, :active => true).map {|a| a.hunt_group_id} + calls = CallHistory.where('(call_historyable_type = "SipAccount" AND call_historyable_id = ?) OR (call_historyable_type = "HuntGroup" AND call_historyable_id IN (?))', @sip_account.id, hunt_group_ids).order('start_stamp DESC') + + @call_histories = calls.paginate( + :page => @pagination_page_number, + :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE + ) + + @calls_count = calls.count + @calls_received_count = calls.where(:entry_type => 'received').count + @calls_dialed_count = calls.where(:entry_type => 'dialed').count + @calls_missed_count = calls.where(:entry_type => 'missed').count + @calls_forwarded_count = calls.where(:entry_type => 'forwarded').count + + if ! @type.blank? + @call_histories = @call_histories.where(:entry_type => @type) + end + end + + + def destroy + @call_history = CallHistory.where(:id => params[:id]).first + if can?(:destroy, @call_history) + @call_history.destroy + m = method( :"#{@parent.class.name.underscore}_call_histories_url" ) + redirect_to m.(), :notice => t('call_histories.controller.successfuly_destroyed') + end + end + + def destroy_multiple + if ! params[:selected_ids].blank? then + result = @sip_account.call_histories.where(:id => params[:selected_ids]).destroy_all(); + end + + m = method( :"#{@parent.class.name.underscore}_call_histories_url" ) + if result + redirect_to m.(), :notice => t('call_histories.controller.successfuly_destroyed') + else + redirect_to m.() + end + end + + def call + @call_history = CallHistory.where(:id => params[:id]).first + if can?(:call, @call_history) && @sip_account.registration + phone_number = @call_history.display_number + if ! phone_number.blank? + @sip_account.call(phone_number) + end + end + redirect_to(:back) + end + + private + def set_and_authorize_parent + @parent = @sip_account + + authorize! :read, @parent + + @show_path_method = method( :"#{@parent.class.name.underscore}_call_history_path" ) + @index_path_method = method( :"#{@parent.class.name.underscore}_call_histories_path" ) + @new_path_method = method( :"new_#{@parent.class.name.underscore}_call_history_path" ) + @edit_path_method = method( :"edit_#{@parent.class.name.underscore}_call_history_path" ) + end + + def spread_breadcrumbs + if @parent.class == SipAccount + if @sip_account.sip_accountable.class == User + add_breadcrumb t("#{@sip_account.sip_accountable.class.name.underscore.pluralize}.index.page_title"), method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore.pluralize}_path" ).(@sip_account.tenant) + add_breadcrumb @sip_account.sip_accountable, method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore}_path" ).(@sip_account.tenant, @sip_account.sip_accountable) + end + add_breadcrumb t("sip_accounts.index.page_title"), method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_accounts_path" ).(@sip_account.sip_accountable) + add_breadcrumb @sip_account, method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_account_path" ).(@sip_account.sip_accountable, @sip_account) + add_breadcrumb t("call_histories.index.page_title"), sip_account_call_histories_path(@sip_account) + if @call_history && !@call_history.new_record? + add_breadcrumb @call_history, sip_account_call_history_path(@sip_account, @call_history) + end + end + end + +end diff --git a/app/controllers/calls_controller.rb b/app/controllers/calls_controller.rb new file mode 100644 index 0000000..d5f3b42 --- /dev/null +++ b/app/controllers/calls_controller.rb @@ -0,0 +1,6 @@ +class CallsController < ApplicationController + + def index + @calls = Call.all + end +end diff --git a/app/controllers/callthroughs_controller.rb b/app/controllers/callthroughs_controller.rb new file mode 100644 index 0000000..f489622 --- /dev/null +++ b/app/controllers/callthroughs_controller.rb @@ -0,0 +1,75 @@ +class CallthroughsController < ApplicationController + load_and_authorize_resource :tenant + load_and_authorize_resource :callthrough, :through => [:tenant] + + before_filter :set_parent_and_path_methods + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @callthrough = @tenant.callthroughs.build + @callthrough.name = generate_a_new_name(@tenant, @callthrough) + @callthrough.phone_numbers.build + @callthrough.access_authorizations.build(:name => "#{t('access_authorizations.name')} #{@callthrough.access_authorizations.count + 1}", :pin => random_pin).phone_numbers.build + @callthrough.whitelists.build.phone_numbers.build + end + + def create + @callthrough = @tenant.callthroughs.build(params[:callthrough]) + if @callthrough.save + redirect_to tenant_callthrough_path(@tenant, @callthrough), :notice => t('callthroughs.controller.successfuly_created') + else + @callthrough.phone_numbers.build if @callthrough.phone_numbers.size == 0 + render :new + end + end + + def edit + @callthrough.phone_numbers.build + @callthrough.access_authorizations.build.phone_numbers.build + if @callthrough.whitelisted_phone_numbers.count == 0 + if @callthrough.whitelists.count == 0 + @callthrough.whitelists.build.phone_numbers.build + else + @callthrough.whitelists.first.phone_numbers.build + end + end + end + + def update + if @callthrough.update_attributes(params[:callthrough]) + redirect_to tenant_callthrough_path(@tenant, @callthrough), :notice => t('callthroughs.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @callthrough.destroy + redirect_to tenant_callthroughs_path(@tenant), :notice => t('callthroughs.controller.successfuly_destroyed') + end + + private + + def set_parent_and_path_methods + @parent = @tenant + @show_path_method = method( :"#{@parent.class.name.underscore}_callthrough_path" ) + @index_path_method = method( :"#{@parent.class.name.underscore}_callthroughs_path" ) + @new_path_method = method( :"new_#{@parent.class.name.underscore}_callthrough_path" ) + @edit_path_method = method( :"edit_#{@parent.class.name.underscore}_callthrough_path" ) + end + + def spread_breadcrumbs + if @parent && @parent.class == Tenant + add_breadcrumb t("callthroughs.name").pluralize, tenant_callthroughs_path(@parent) + if @callthrough && !@callthrough.new_record? + add_breadcrumb @callthrough, tenant_callthrough_path(@parent, @callthrough) + end + end + end +end diff --git a/app/controllers/conference_invitees_controller.rb b/app/controllers/conference_invitees_controller.rb new file mode 100644 index 0000000..ce55b5a --- /dev/null +++ b/app/controllers/conference_invitees_controller.rb @@ -0,0 +1,93 @@ +class ConferenceInviteesController < ApplicationController + load_and_authorize_resource :conference + load_and_authorize_resource :conference_invitee, :through => [:conference] + + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @conference_invitee = @conference.conference_invitees.build + @conference_invitee.speaker = true + @conference_invitee.moderator = false + @phone_number = @conference_invitee.build_phone_number + end + + def create + @conference_invitee = @conference.conference_invitees.build(params[:conference_invitee]) + + # Try to find this phone_number in phone_books the current_user can read. + # Save the found entry as phone_book_entry. + # + @conference_invitee.phone_number.parse_and_split_number! + phone_numbers = PhoneNumber.where(:number => @conference_invitee.phone_number.number). + where(:phone_numberable_type => 'PhoneBookEntry') + phone_numbers.each do |phone_number| + phone_book = phone_number.phone_numberable.phone_book + if can?(:read, phone_book) + @conference_invitee.phone_book_entry = phone_number.phone_numberable + break + end + end + + if @conference_invitee.save + # m = method( :"#{@parent_in_route.class.name.underscore}_path" ) + # redirect_to m.( @parent_in_route ), :notice => t('conference_invitees.controller.successfuly_created', :resource => @conference_invitees) + m = method( :"#{@conference_invitee.conference.conferenceable_type.underscore}_conference_path") + redirect_to m.( @conference_invitee.conference.conferenceable, @conference_invitee.conference), :notice => t('conference_invitees.controller.successfuly_created', :resource => @conference_invitees) + else + render :new + end + end + + def edit + authorize! :edit, @parent_in_route + end + + def update + if @conference_invitee.update_attributes(params[:conference_invitee]) + redirect_to @conference_invitee, :notice => t('conference_invitees.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @conference_invitee.destroy + redirect_to conference_invitees_url, :notice => t('conference_invitees.controller.successfuly_destroyed') + end + + private + + def spread_breadcrumbs + if @conference + @parent = @conference.conferenceable + if @parent && @parent.class == User + @user = @parent + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_users_path(@user.current_tenant, @user) + add_breadcrumb t("conferences.index.page_title"), user_conferences_path(@user) + if @conference && !@conference.new_record? + add_breadcrumb @conference, user_conference_path(@user, @conference) + end + end + if @parent && @parent.class == Tenant + @tenant = @parent + add_breadcrumb t("conferences.index.page_title"), tenant_conferences_path(@tenant) + if @conference && !@conference.new_record? + add_breadcrumb @conference, tenant_conference_path(@tenant, @conference) + end + end + + add_breadcrumb t("conference_invitees.index.page_title"), conference_conference_invitees_path(@conference) + if @conference_invitee && !@conference_invitee.new_record? + add_breadcrumb @conference_invitee, conference_conference_invitee_path(@conference, @conference_invitee) + end + end + end + +end diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb new file mode 100644 index 0000000..302a23b --- /dev/null +++ b/app/controllers/conferences_controller.rb @@ -0,0 +1,82 @@ +class ConferencesController < ApplicationController + load_resource :user + load_resource :tenant + load_and_authorize_resource :conference, :through => [:user, :tenant] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + @phone_numbers = @conference.phone_numbers + end + + def new + @conference = @parent.conferences.build + @conference.name = generate_a_new_name(@parent, @conference) + @conference.start = nil + @conference.end = nil + @conference.open_for_anybody = true + @conference.max_members = DEFAULT_MAX_CONFERENCE_MEMBERS + @conference.pin = random_pin + + @conference.open_for_anybody = true + @conference.announce_new_member_by_name = true + @conference.announce_left_member_by_name = true + end + + def create + @conference = @parent.conferences.build(params[:conference]) + if @conference.save + m = method( :"#{@parent.class.name.underscore}_conference_path" ) + redirect_to m.( @parent, @conference ), :notice => t('conferences.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @conference.update_attributes(params[:conference]) + m = method( :"#{@parent.class.name.underscore}_conference_path" ) + redirect_to m.( @parent, @conference ), :notice => t('conferences.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @conference.destroy + m = method( :"#{@parent.class.name.underscore}_conferences_url" ) + redirect_to m.( @parent ), :notice => t('conferences.controller.successfuly_destroyed') + end + + private + + def set_and_authorize_parent + @parent = @tenant || @user + authorize! :read, @parent + end + + def spread_breadcrumbs + if @parent && @parent.class == User + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t("conferences.index.page_title"), user_conferences_path(@user) + if @conference && !@conference.new_record? + add_breadcrumb @conference, user_conference_path(@user, @conference) + end + end + if @parent && @parent.class == Tenant + add_breadcrumb t("conferences.index.page_title"), tenant_conferences_path(@tenant) + if @conference && !@conference.new_record? + add_breadcrumb @conference, tenant_conference_path(@tenant, @conference) + end + end + end + +end diff --git a/app/controllers/config_polycom_controller.rb b/app/controllers/config_polycom_controller.rb new file mode 100644 index 0000000..9d44e51 --- /dev/null +++ b/app/controllers/config_polycom_controller.rb @@ -0,0 +1,330 @@ +class ConfigPolycomController < ApplicationController + MAX_SIP_ACCOUNTS_COUNT = 11 + MAX_SOFTKEYS_COUNT = 12 + MAX_DIRECTORY_ENTRIES = 20 + SIP_DEFAULT_PORT = 5060 + + skip_authorization_check + + before_filter { |controller| + if ! params[:mac_address].blank? then + @mac_address = params[:mac_address].upcase.gsub(/[^0-9A-F]/,'') + @phone = Phone.where({ :mac_address => @mac_address }).first + elsif ! params[:phone].blank? then + @phone = Phone.where({ :id => params[:phone].to_i }).first + end + + if ! @phone + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Phone not found -->", + ) + return false + end + + if ! params[:sip_account].blank? + @sip_account = @phone.sip_accounts.where({ :id => params[:sip_account].to_i }).first + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return false + end + end + + if ! params[:type].blank? + @type = params[:type].to_s.strip.downcase + end + } + + def config_files + if params[:mac_address].blank? then + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- MAC not specified -->", + ) + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render + } + } + end + + def settings + if ! request.env['HTTP_USER_AGENT'].index('polycom') + Rails.logger.info "---> User-Agent indicates not a Polycom phone (#{request.env['HTTP_USER_AGENT'].inspect})" + else + Rails.logger.info "---> Phone #{@mac_address.inspect}, IP address #{request.remote_ip.inspect}" + @phone.update_attributes({ :ip_address => request.remote_ip }) + end + + xml_applications_url = "#{request.protocol}#{request.host_with_port}/config_polycom/#{@phone.id}/0" + + @settings = { + 'device.sntp.serverName' => 'pool.ntp.org', + 'device.sntp.gmtOffset' => 3600, + 'up.welcomeSoundOnWarmBootEnabled' => 0, + 'up.welcomeSoundEnabled' => 0, + 'bg.hiRes.color.selection' => '2,1', + 'msg.mwi.1.callBackMode' => 'contact', + 'msg.mwi.1.callBack' => 'f-vmcheck', + 'feature.enhancedFeatureKeys.enabled' => 1, + 'softkey.feature.basicCallManagement.redundant' => 0, + 'softkey.feature.buddies' => 0, + 'softkey.feature.callers' => 0, + 'softkey.feature.directories' => 0, + 'softkey.feature.endcall' => 1, + 'softkey.feature.forward' => 0, + 'softkey.feature.mystatus' => 0, + 'softkey.feature.newcall' => 0, + 'call.directedCallPickupMethod' => 'legacy', + 'call.directedCallPickupString' => 'f-ia-', + 'call.advancedMissedCalls.enabled' => 0, + 'lineKey.reassignment.enabled' => 1, + 'lineKey.1.category' => 'Line', + 'lineKey.1.index' => 1, + } + + for key_index in 2..42 + @settings["lineKey.#{key_index}.category"] = 'Unassigned' + end + + for ring_class in 1..17 + @settings["se.rt.custom#{ring_class}.name"] = "Ringer#{ring_class-1}" + @settings["se.rt.custom#{ring_class}.ringer"] = "ringer#{ring_class}" + end + @settings["se.rt.custom1.type"] = 'visual' + + for ring_class in 1..17 + @settings["voIpProt.SIP.alertInfo.#{ring_class}.class"] = "custom#{ring_class}" + @settings["voIpProt.SIP.alertInfo.#{ring_class}.value"] = "Ringer#{ring_class-1}" + end + + softkey_index = 1 + blf_index = 0 + + @phone.sip_accounts.each do |sip_account| + sip_account_index = 0 + if (sip_account.sip_accountable_type == @phone.phoneable_type) and (sip_account.sip_accountable_id == @phone.phoneable_id) + sip_account_index += 1 + if sip_account_index == 1 + xml_applications_url = "#{request.protocol}#{request.host_with_port}/config_polycom/#{@phone.id}/#{sip_account.id}" + @settings['voIpProt.SIP.outboundProxy.address'] = sip_account.host + @settings['voIpProt.SIP.outboundProxy.port'] = SIP_DEFAULT_PORT + end + + @settings["reg.#{sip_account_index}.address"] = "#{sip_account.auth_name}@#{sip_account.host}" + @settings["reg.#{sip_account_index}.auth.password"] = sip_account.password + @settings["reg.#{sip_account_index}.auth.userId"] = sip_account.auth_name + @settings["reg.#{sip_account_index}.displayName"] = 'Call' + @settings["reg.#{sip_account_index}.label"] = sip_account.caller_name + @settings["voIpProt.server.#{sip_account_index}.address"] = sip_account.host + @settings["voIpProt.server.#{sip_account_index}.port"] = SIP_DEFAULT_PORT + @settings["call.missedCallTracking.#{sip_account_index}.enabled"] = 0 + + sip_account.softkeys.order(:position).each do |softkey| + softkey_index += 1 + if softkey.softkey_function + softkey_function = softkey.softkey_function.name + end + case softkey_function + when 'blf' + blf_index += 1 + @settings["lineKey.#{softkey_index}.category"] = 'BLF' + @settings["attendant.resourceList.#{blf_index}.address"] = "#{softkey.number}@#{sip_account.host}" + @settings["attendant.resourceList.#{blf_index}.label"] = softkey.label + end + end + end + end + + @settings['mb.idleDisplay.home'] = "#{xml_applications_url}/idle_screen.xml" + @settings['mb.idleDisplay.refresh'] = 60 + + @settings['efk.efklist.1.mname'] = "directory" + @settings['efk.efklist.1.status'] = 1 + @settings['efk.efklist.1.action.string'] = "#{xml_applications_url}/phone_book.xml" + @settings['efk.efklist.2.mname'] = "callhistory" + @settings['efk.efklist.2.status'] = 1 + @settings['efk.efklist.2.action.string'] = "#{xml_applications_url}/call_history.xml" + @settings['efk.efklist.3.mname'] = "applications" + @settings['efk.efklist.3.status'] = 1 + @settings['efk.efklist.3.action.string'] = "#{xml_applications_url}/applications.xml" + + @settings['softkey.1.action'] = "#{xml_applications_url}/phone_book.xml" + @settings['softkey.1.enable'] = 1 + @settings['softkey.1.insert'] = 1 + @settings['softkey.1.label'] = 'Directory' + @settings['softkey.1.precede'] = 1 + @settings['softkey.1.use.active'] = 1 + @settings['softkey.1.use.alerting'] = 0 + @settings['softkey.1.use.dialtone'] = 1 + @settings['softkey.1.use.hold'] = 1 + @settings['softkey.1.use.idle'] = 1 + @settings['softkey.1.use.proceeding'] = 0 + @settings['softkey.1.use.setup'] = 0 + @settings['softkey.2.action'] = "#{xml_applications_url}/call_history.xml" + @settings['softkey.2.enable'] = 1 + @settings['softkey.2.insert'] = 2 + @settings['softkey.2.label'] = 'Call History' + @settings['softkey.2.precede'] = 1 + @settings['softkey.2.use.active'] = 1 + @settings['softkey.2.use.alerting'] = 0 + @settings['softkey.2.use.dialtone'] = 1 + @settings['softkey.2.use.hold'] = 1 + @settings['softkey.2.use.idle'] = 1 + @settings['softkey.2.use.proceeding'] = 0 + @settings['softkey.2.use.setup'] = 0 + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render + } + } + end + + + def settings_directory + respond_to { |format| + format.any { + self.formats = [ :xml ] + render + } + } + end + + + def call_history + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + if ['dialed', 'missed', 'received'].include? @type + @phone_xml_object = { + :name => "call_history", + :title => @type.titleize, + :entries => [] + } + + calls = @sip_account.call_histories.where(:entry_type => @type).order('start_stamp DESC').limit(MAX_DIRECTORY_ENTRIES) + + calls.each do |call| + display_name = call.display_name + phone_number = call.display_number + phone_book_entry = call.phone_book_entry_by_number(phone_number) + if display_name.blank? + display_name = phone_book_entry.to_s + end + + @phone_xml_object[:entries].push({ + :selected => false, + :number => phone_number, + :date => call.start_stamp.strftime('%d.%m %H:%M'), + :text => display_name, + :url => "tel:#{phone_number}", + }) + end + else + base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" + @phone_xml_object = { + :name => 'call_history_menu', + :title => 'Call History Lists', + :entries => [ + {:text => 'Missed Calls', :url => "#{base_url}?&type=missed", :selected => false}, + {:text => 'Received Calls', :url => "#{base_url}?&type=received", :selected => false}, + {:text => 'Placed Calls', :url => "#{base_url}?&type=dialed", :selected => false}, + ] + } + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}", :content_type => Mime::HTML + } + } + + end + + + def phone_book + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + @phone_xml_object = { + :name => 'phone_book', + :title => "Phone Book".strip, + :entries => [], + :softkeys => [], + } + + phone_books = Array.new() + phone_books = phone_books + @sip_account.sip_accountable.try(:phone_books).all + if @sip_account.sip_accountable.class == User + phone_books = phone_books + @sip_account.sip_accountable.try(:current_tenant).try(:phone_books).all + end + + phone_book_ids = Array.new() + phone_books.each do |phone_book| + phone_book_ids << phone_book.id + end + + PhoneBookEntry.where(:phone_book_id => phone_book_ids).order(:last_name).order(:first_name).limit(MAX_DIRECTORY_ENTRIES).each do |phone_book_entry| + phone_numbers_count = 0 + phone_book_entry.phone_numbers.each do |phone_number| + phone_numbers_count += 1 + if phone_numbers_count > 1 + entry_name = '' + else + entry_name = phone_book_entry.to_s + end + + @phone_xml_object[:entries] << { :text => entry_name, :type => phone_number.name, :number => phone_number.number, :url => "tel:#{phone_number.number}" } + end + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}", :content_type => Mime::HTML + } + } + + end + + + def idle_screen + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "idle_screen", :content_type => Mime::HTML + } + } + end +end diff --git a/app/controllers/config_siemens_controller.rb b/app/controllers/config_siemens_controller.rb new file mode 100644 index 0000000..f398b1a --- /dev/null +++ b/app/controllers/config_siemens_controller.rb @@ -0,0 +1,1239 @@ +require 'nokogiri' +#doc.search('Message/ItemList').each do |a| puts a.children end +class ConfigSiemensController < ApplicationController +#TODO Authentication + # No access for admins though as this contains personal data. + + # We can't use load_and_authorize_resource() here because + # ConfigSiemensController isn't a resource. + # We can try client certificates + MAX_DIRECTORY_ENTRIES = 20 + + skip_authorization_check + + before_filter { |controller| + if ! params[:phone].blank? + @phone = Phone.where({ :id => params[:phone].to_i }).first + end + + if ! params[:sip_account].blank? + @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first + end + + if ! @sip_account && @phone + @sip_account = @phone.sip_accounts.where(:sip_accountable_id => @phone.phoneable_id, :sip_accountable_type => @phone.phoneable_type).first + end + } + + + def index + os40_keys=6 + os60_keys=8 + os80_keys=9 + doc = Nokogiri::XML(request.body.read) + #logger.debug("#{params[:WorkpointMessage].to_xml}") + #logger.debug("#{params[:WorkpointMessage][:Message][:ItemList].to_xml}") + @phone_items=Hash.new + contact_reason = params[:WorkpointMessage][:Message][:ReasonForContact] + fragment = params[:WorkpointMessage][:Message][:fragment] + + reply_status = doc.search('Message/ReasonForContact').first[:status] + reply_action = doc.search('Message/ReasonForContact').first[:action] + + doc.search('Message/ItemList/Item').each do |post_item| + @phone_items[post_item[:name]]=post_item.children.to_s + end + if @phone_items['mac-addr'] + mac_address = @phone_items['mac-addr'] + end + phone_type = @phone_items['device-type'] + if phone_type == "OpenStage 40" + max_keys = (os40_keys) * 2 + elsif phone_type == "OpenStage 60" + max_keys = (os60_keys) * 2 + elsif phone_type == "OpenStage 80" + max_keys = (os80_keys) * 2 + else + max_keys = 0 + end + + blf_keys_max = max_keys / 2 + shift_key_position = blf_keys_max + + #logger.debug(request.body.read) + if mac_address + @phone = Phone.find_by_mac_address(mac_address.gsub(':','').upcase) + + if ! @phone && PROVISIONING_AUTO_ADD_PHONE + tenant = Tenant.where(:id => PROVISIONING_AUTO_TENANT_ID).first + if ! tenant + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Tenant not found -->", + ) + return + end + + @phone = tenant.phones.build + @phone.mac_address = mac_address + @phone.hot_deskable = true + @phone.phone_model = PhoneModel.where('name LIKE ?', "#{phone_type}").first + if ! @phone.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{@phone.errors.messages.inspect} -->", + ) + return + end + + if ! PROVISIONING_AUTO_ADD_SIP_ACCOUNT + return + end + + caller_name_index = 0 + sip_account_last = tenant.sip_accounts.where('caller_name LIKE ?', "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}%").sort { |item1, item2| + item1.caller_name.gsub(/[^0-9]/, '').to_i <=> item2.caller_name.gsub(/[^0-9]/, '').to_i + }.last + + if sip_account_last + caller_name_index = sip_account_last.caller_name.gsub(/[^0-9]/, '').to_i + end + caller_name_index = caller_name_index + 1 + + @sip_account = tenant.sip_accounts.build + @sip_account.caller_name = "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}#{caller_name_index}" + @sip_account.call_waiting = CALL_WAITING + @sip_account.clir = DEFAULT_CLIR_SETTING + @sip_account.clip = DEFAULT_CLIP_SETTING + @sip_account.voicemail_pin = random_pin + @sip_account.callforward_rules_act_per_sip_account = CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT + @sip_account.hotdeskable = false + loop do + @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME) + break unless SipAccount.exists?(:auth_name => @sip_account.auth_name) + end + @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD) + + if ! @sip_account.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{@sip_account.errors.messages.inspect} -->", + ) + return + end + + phone_sip_account = PhoneSipAccount.new() + phone_sip_account.phone_id = @phone.id + phone_sip_account.sip_account_id = @sip_account.id + + if ! phone_sip_account.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{phone_sip_account.errors.messages.inspect} -->", + ) + return + end + end + end + + + country = 'US' + language = 'en' + if ! @phone.nil? + @phone.update_attributes(:ip_address => request.remote_ip) + @sip_account = @phone.sip_accounts.where(:sip_accountable_type => @phone.phoneable_type, + :sip_accountable_id => @phone.phoneable_id).first + + if @phone.phoneable + if @phone.phoneable_type == 'Tenant' + tenant = @phone.phoneable + language = tenant.language.code + elsif @phone.phoneable_type == 'User' + language = @phone.phoneable.language.code + tenant = @phone.phoneable.current_tenant + end + end + + if tenant && tenant.country + country_map = { + '61' => 'AU', # Australia + '43' => 'AT', # Austria + '86' => 'CN', # China + '45' => 'DK', # Denmark + '33' => 'FA', # France + '49' => 'DE', # Germany + '44' => 'GB', # Great Britain + '91' => 'IN', # India + '39' => 'IT', # Italy + '81' => 'JP', # Japan + '52' => 'MX', # Mexico + '31' => 'NL', # Netherlands + '47' => 'NO', # Norway + '64' => 'NZ', # New Zealand + '34' => 'ES', # Spain + '46' => 'SE', # Sweden + '41' => 'CH', # Switzerland + } + if country_map.include?(tenant.country.country_code) + country = country_map[tenant.country.country_code] + end + end + end + + if ! @phone.nil? && ! @sip_account.blank? + #logger.debug(@phone_items) + @my_nonce = params[:WorkpointMessage][:Message][:nonce] + @new_settings = Array.new + + @new_settings << ['dhcp', nil, 'true'] + @new_settings << ['hostname', nil, mac_address.gsub(':', '') ] + #@new_settings << ['e164-hostname', nil, 'false'] + @new_settings << ['mobility-enabled', nil, 'false'] + @new_settings << ['mobility-password-on-logoff', nil, 'false'] + @new_settings << ['e164', nil, @sip_account.auth_name] + @new_settings << ['sip-user-id', nil, @sip_account.auth_name] + #Not supported + #@new_settings << ['reg-id', nil, @sip_account.auth_name] + #@new_settings << ['reg-number', nil, @sip_account.auth_name] + #@new_settings << ['fully-qualified-phone-no', nil, @sip_account.auth_name] + @new_settings << ['sip-pwd', nil, @sip_account.password] + @new_settings << ['sip-name', nil, @sip_account.caller_name] + @new_settings << ['register-by-name', nil, 'false'] + @new_settings << ['display-id-unicode', nil, @sip_account.caller_name] + @new_settings << ['use-display-id', nil, 'true'] + @new_settings << ['reg-addr', nil, @sip_account.sip_domain.host] + @new_settings << ['reg-port', nil, '5060'] + @new_settings << ['registrar-addr', nil, @sip_account.sip_domain.host] + @new_settings << ['registrar-port', nil, '5060'] + #@new_settings << ['outbound-proxy', nil, @sip_account.sip_domain.host] + @new_settings << ['outbound-proxy-user', nil, @sip_account.auth_name] + #@new_settings << ['sgnl-gateway-addr', nil, @sip_account.sip_domain.host] + #@new_settings << ['sgnl-gateway-port', nil, '5060' ] + @new_settings << ['sgnl-gateway-addr-user', nil, @sip_account.sip_domain.host] + @new_settings << ['sgnl-gateway-port-user', nil, '5060'] + @new_settings << ['sgnl-route', nil, '0' ] + @new_settings << ['mwi-e164', nil, '' ] + @new_settings << ['rtp-base-port', nil, '5004'] + @new_settings << ['default-domain', nil, '' ] + #@new_settings << ['sip-transport', nil, '0' ] + @new_settings << ['sip-transport-user', nil, '0' ] + @new_settings << ['server-type', nil, '0' ] + @new_settings << ['session-timer', nil, 'false' ] + @new_settings << ['session-duration', nil, '3600' ] + @new_settings << ['reg-ttl', nil, '3600' ] + @new_settings << ['realm', nil, @sip_account.sip_domain.realm] + @new_settings << ['emergency-e164', nil, '0110' ] + @new_settings << ['voice-mail-e164', nil, 'f-vmcheck'] + @new_settings << ['auto-answer', nil, 'false'] + @new_settings << ['beep-on-auto-answer', nil, 'true'] + @new_settings << ['auto-reconnect', nil, 'false' ] + @new_settings << ['beep-on-auto-reconnect', nil, 'true'] + #@new_settings << ['permit-decline-call', nil, 'true'] + @new_settings << ['transfer-on-ring', nil, 'false' ] + @new_settings << ['join-allowed-in-conference', nil, 'true'] + @new_settings << ['pickup-group-uri', nil, "f-ig-#{@sip_account.id}"] + @new_settings << ['pickup-group-uri', nil, '' ] + @new_settings << ['hot-line-warm-line-digits', nil, '' ] + @new_settings << ['initial-digit-timer', nil, '30' ] + @new_settings << ['conference-factory-uri', nil, ''] + @new_settings << ['callback-busy-allow', nil, 'false'] + @new_settings << ['callback-busy-code', nil, '' ] + @new_settings << ['callback-ring-allow', nil, 'false'] + @new_settings << ['callback-ring-code', nil, ''] + @new_settings << ['callback-cancel-code', nil, ''] + @new_settings << ['park-server', nil, ''] + #OPTIMIZE Callwaiting + @new_settings << ['call-waiting-enabled', nil, 'true'] + @new_settings << ['qos-layer2', nil, 'true'] + @new_settings << ['l2qos-voice', nil, '5' ] + @new_settings << ['l2qos-signalling', nil, '3' ] + @new_settings << ['l2qos-default', nil, '0'] + @new_settings << ['qos-layer3', nil, 'true'] + @new_settings << ['l3qos-voice', nil, '46'] + @new_settings << ['l3qos-signalling', nil, '26'] + @new_settings << ['vlan-method', nil, '1'] + #OPTIMIZE Timezone settings + @new_settings << ['time', nil, Time.new.localtime.to_i] + @new_settings << ['sntp-addr', nil, 'NULL'] + @new_settings << ['sntp-tz-offset', nil, (Time.new.utc_offset/60).to_i] + @new_settings << ['daylight-save', nil, 'true'] + @new_settings << ['daylight-save-minutes', nil, '0'] + @new_settings << ['auto-daylight-save', nil, 'true'] + @new_settings << ['daylight-save-zone-id', nil, '9'] + #OPTIMIZE Use SNMP? + @new_settings << ['snmp-trap-addr', nil, 'NULL'] + @new_settings << ['snmp-trap-port', nil, '162'] + @new_settings << ['snmp-trap-pwd', nil, 'snmp' ] + @new_settings << ['snmp-traps-active', nil, 'false' ] + @new_settings << ['diagnostic-trap-addr', nil, 'NULL'] + @new_settings << ['diagnostic-trap-port', nil, '162'] + @new_settings << ['diagnostic-trap-pwd', nil, 'snmp' ] + @new_settings << ['diagnostic-traps-active', nil, 'false' ] + @new_settings << ['diagnostic-snmp-active', nil, 'false'] + @new_settings << ['qdc-collection-unit-addr', nil, 'NULL'] + @new_settings << ['qdc-collection-unit-port', nil, '12010'] + + @new_settings << ['qdc-trap-pwd', nil, 'QOSDC'] + @new_settings << ['qdc-snmp-active', nil, 'false'] + @new_settings << ['qdc-qcu-active', nil, 'false'] + @new_settings << ['snmp-queries-allowed', nil, 'false'] + #@new_settings << ['snmp-pwd', nil, ''] + @new_settings << ['disable-microphone', nil, 'false'] + @new_settings << ['loudspeech-enabled', nil, 'true'] + @new_settings << ['audio-silence-suppression', nil, 'false'] + + @new_settings << ['port1', nil, '0' ] # 0=Automatic (speed) + @new_settings << ['port2', nil, '0' ] + @new_settings << ['port2-mode', nil, '1' ] + @new_settings << ['port2-auto-mdix-enabled', nil, 'true' ] + @new_settings << ['originating-line-preference', nil, '0'] + @new_settings << ['terminating-line-preference', nil, '0'] + @new_settings << ['line-key-operating-mode', nil, '0'] + @new_settings << ['line-rollover-type', nil, '2'] + @new_settings << ['line-rollover-volume', nil, '5' ]# 1-5 + @new_settings << ['line-registration-leds', nil, 'true'] + @new_settings << ['keyset-use-focus', nil, 'true' ] + @new_settings << ['keyset-remote-forward-ind', nil, 'true'] + @new_settings << ['keyset-reservation-timer', nil, '60' ] # 0-300 + @new_settings << ['dial-plan-enabled', nil, 'false' ] + @new_settings << ['Canonical-dialing-international-prefix', nil, ''] + @new_settings << ['Canonical-dialing-local-country-code', nil, ''] + @new_settings << ['Canonical-dialing-national-prefix', nil, ''] + @new_settings << ['Canonical-dialing-local-area-code', nil, ''] + @new_settings << ['Canonical-dialing-local-node', nil, ''] + @new_settings << ['Canonical-dialing-external-access', nil, '0'] + @new_settings << ['Canonical-dialing-operator-code', nil, ''] + @new_settings << ['Canonical-dialing-emergency-number', nil, ''] + @new_settings << ['Canonical-dialing-dial-needs-access-code', nil, '0'] + @new_settings << ['Canonical-dialing-dial-needs-intGWcode', nil, '1'] + @new_settings << ['Canonical-dialing-min-local-number-length', nil, '10'] + @new_settings << ['Canonical-dialing-extension-initial-digits', nil, ''] + @new_settings << ['Canonical-dialing-dial-internal-form', nil, '0' ] + @new_settings << ['Canonical-dialing-dial-external-form', nil, '0' ] + #@new_settings << ['Canonical-lookup-local-code', nil, '' ] + #@new_settings << ['Canonical-lookup-international-code', nil, ''] + @new_settings << ['hot-keypad-dialing', nil, 'false'] + @new_settings << ['ldap-transport', nil, '0'] + @new_settings << ['ldap-server-address', nil, 'NULL' ] + @new_settings << ['ldap-server-port', nil, '389' ] + @new_settings << ['ldap-authentication', nil, '1'] + @new_settings << ['ldap-user', nil, 'NULL' ] + @new_settings << ['ldap-pwd', nil, 'NULL' ] + @new_settings << ['ldap-max-responses', nil, '25'] + @new_settings << ['backup-addr', nil, 'NULL'] + @new_settings << ['backup-registration', nil, 'false'] + @new_settings << ['qdc-qcu-active', nil, 'false' ] + @new_settings << ['min-admin-passw-length', nil, '6' ] + #@new_settings << ['default-locked-config-menus', nil, 'true' ] + @new_settings << ['locked-config-menus', nil, 'true' ] + #@new_settings << ['default-locked-local-function-menus', nil, 'true' ] + @new_settings << ['locked-local-function-menus', nil, 'true' ] + #@new_settings << ['dls-mode-secure', nil, '0' ] + @new_settings << ['dls-chunk-size', nil, '9492'] + #@new_settings << ['default-passw-policy', nil, 'false'] + @new_settings << ['deflect-destination', nil, ''] + @new_settings << ['display-skin', nil, (@phone.phoneable_type == 'User' ? '0' : '1')] + @new_settings << ['enable-bluetooth-interface', nil, 'true'] + @new_settings << ['usb-access-enabled', nil, 'false' ] + @new_settings << ['usb-backup-enabled', nil, 'false' ] + @new_settings << ['line-button-mode', nil, '0' ] + @new_settings << ['lock-forwarding', nil, '' ] + @new_settings << ['loudspeaker-function-mode', nil, '0' ] + @new_settings << ['max-pin-retries', nil, '10' ] + @new_settings << ['screensaver-enabled', nil, 'false' ] + @new_settings << ['inactivity-timeout', nil, '60' ] + @new_settings << ['not-used-timeout', nil, '5' ] + @new_settings << ['passw-char-set', nil, '0' ] + @new_settings << ['refuse-call', nil, 'true' ] + @new_settings << ['restart-password', nil, '124816'] + #OPTIMIZE clock format + @new_settings << ['time-format', nil, '0' ]# 1=12 h + @new_settings << ['uaCSTA-enabled', nil, 'false' ] + @new_settings << ['enable-test-interface', nil, 'false'] + @new_settings << ['enable-WBM', nil, 'true'] + #@new_settings << ['pixelsaver-timeout', nil, '2' ]# 2 hours? + #@new_settings << ['voice-message-dial-tone', nil, '' ] + #@new_settings << ['call-pickup-allowed', nil, 'true' ] + @new_settings << ['group-pickup-tone-allowed', nil, 'true'] + @new_settings << ['group-pickup-as-ringer', nil, 'false'] + @new_settings << ['group-pickup-alert-type', nil, '0' ] + #@new_settings << ['default-profile', nil, '' ] + @new_settings << ['count-medium-priority', nil, '5'] + @new_settings << ['timer-medium-priority', nil, '60'] # 1 - 999 + @new_settings << ['timer-high-priority', nil, '5'] # 0 - 999 + @new_settings << ['dss-sip-detect-timer', nil, '10'] + @new_settings << ['dss-sip-deflect', nil, 'false' ] + @new_settings << ['dss-sip-refuse', nil, 'false' ] + @new_settings << ['feature-availability', nil, 'false'] + @new_settings << ['feature-availability', nil, 'true' ] + @new_settings << ['feature-availability', nil, 'true' ] + @new_settings << ['local-control-feature-availability', nil, 'false' ] + @new_settings << ['trace-level', nil, '0' ] # Off + #@new_settings << ['default-locked-function-keys', nil, 'true' ]# "unknown item" + @new_settings << ['blf-code', nil, 'f-ia-'] # pickup prefix for softkey function 59 (BLF) + @new_settings << ['stimulus-feature-code', nil, true] + @new_settings << ['stimulus-led-control-uri', nil, true] + + @new_settings << ['min-user-passw-length', nil, '6' ]# 6 - 24 + #OPTIMIZE language + @new_settings << ['country-iso', nil, country ] + @new_settings << ['language-iso', nil, language] + @new_settings << ['date-format', nil, '0' ] # DD.MM.YYYY + #OPTIMIZE ringtones + @new_settings << ['ringer-melody', nil, '1'] + + @new_settings << ['ringer-melody', nil, '2'] + @new_settings << ['ringer-tone-sequence', nil, '2'] + + 1.upto(8) do |index| + @new_settings << ['alert', index, "Ringer#{index}^#{index}^2^60"] + end + @new_settings << ['alert', 9, "Ringer9^1^1^60"] + @new_settings << ['alert', 10, "Ringer10^1^3^60"] + @new_settings << ['alert', 11, "Ringer0^0^2^60"] + + #Applications + @new_settings << ['XML-app-name', 1, 'call_history'] + @new_settings << ['XML-app-control-key', 1, '3'] + @new_settings << ['XML-app-action', 1, 'update'] + @new_settings << ['XML-app-display-name', 1, 'Call History'] + @new_settings << ['XML-app-program-name', 1, "config_siemens/#{@phone.id}/call_history.xml"] + @new_settings << ['XML-app-special-instance', 1, '3'] + @new_settings << ['XML-app-server-addr', 1, request.host] + @new_settings << ['XML-app-server-port', 1, '80'] + @new_settings << ['XML-app-transport', 1, '0'] + @new_settings << ['XML-app-proxy-enabled', 1, 'false'] + @new_settings << ['XML-app-remote-debug', 1, 'false'] + @new_settings << ['XML-app-debug-prog-name', 1, ''] + @new_settings << ['XML-app-num-tabs', 1, '3'] + @new_settings << ['XML-app-restart', 1, 'true'] + @new_settings << ['XML-app-auto-start', 1, 'true'] + @new_settings << ['XML-app-tab1-display-name', 1, 'Missed'] + @new_settings << ['XML-app-tab1-name', 1, 'call_history'] + @new_settings << ['XML-app-tab2-display-name', 1, 'Received'] + @new_settings << ['XML-app-tab2-name', 1, 'call_history_received'] + @new_settings << ['XML-app-tab3-display-name', 1, 'Dialed'] + @new_settings << ['XML-app-tab3-name', 1, 'call_history_dialed'] + + @new_settings << ['XML-app-name', 2, 'menu'] + @new_settings << ['XML-app-control-key', 2, '6'] + @new_settings << ['XML-app-action', 2, 'update'] + @new_settings << ['XML-app-display-name', 2, 'Menu'] + @new_settings << ['XML-app-program-name', 2, "config_siemens/#{@phone.id}/menu.xml"] + @new_settings << ['XML-app-special-instance', 2, '0'] + @new_settings << ['XML-app-server-addr', 2, request.host] + @new_settings << ['XML-app-server-port', 2, '80'] + @new_settings << ['XML-app-transport', 2, '0'] + @new_settings << ['XML-app-proxy-enabled', 2, 'false'] + @new_settings << ['XML-app-remote-debug', 2, 'false'] + @new_settings << ['XML-app-debug-prog-name', 2, ''] + @new_settings << ['XML-app-num-tabs', 2, '3'] + @new_settings << ['XML-app-restart', 2, 'true'] + @new_settings << ['XML-app-tab1-display-name', 2, "Gemeinschaft #{GEMEINSCHAFT_VERSION}"] + @new_settings << ['XML-app-tab1-name', 2, 'menu'] + @new_settings << ['XML-app-tab2-display-name', 2, 'Status'] + @new_settings << ['XML-app-tab2-name', 2, 'menu_status'] + @new_settings << ['XML-app-tab3-display-name', 2, 'Help'] + @new_settings << ['XML-app-tab3-name', 2, 'menu_help'] + + + @new_settings << ['clear-calllog', nil, 'true'] + @new_settings << ['server-based-features', nil, 'true'] + + + if ! @sip_account.call_forwards.blank? + call_forwarding_object = @sip_account.call_forwards.where(:call_forward_case_id => CallForwardCase.where(:value => 'always').first).first + if call_forwarding_object + @new_settings << ['key-functionality', 4002, '1'] + @new_settings << ['function-key-def', 4002, '63'] + @new_settings << ['stimulus-led-control-uri', 4002, "f-cftg-#{call_forwarding_object.id}" ] + @new_settings << ['send-url-address', 4002, request.host] + @new_settings << ['send-url-protocol', 4002, 3] # 0=https, 3=http + @new_settings << ['send-url-port', 4002, '80'] + @new_settings << ['send-url-path', 4002, "/config_siemens/#{@phone.id}/#{@sip_account.id}/call_forwarding.xml"] + @new_settings << ['send-url-query', 4002, "id=#{call_forwarding_object.id}&function=toggle"] + @new_settings << ['send-url-method', 4002, '0'] # 0=get, 1=post + else + @new_settings << ['key-functionality', 4002, '0'] + end + else + @new_settings << ['key-functionality', 4002, '0'] + end + + @new_settings << ['function-key-def', 4003, '10'] # Hold + + @new_settings << ['feature-availability', 2, 'false' ] # call forwarding + @new_settings << ['feature-availability', 11, 'false' ] # DND + @new_settings << ['feature-availability', 30, 'false'] # DSS + @new_settings << ['feature-availability', 31, 'false'] # feature toggle + @new_settings << ['feature-availability', 33, 'true'] # line overview + @new_settings << ['feature-availability', 33, 'false'] # phone lock + + + @soft_keys = Array.new + # Fill softkeys with keys dependent on limit of phone + @sip_account.softkeys.order(:position).each do |sk| + @soft_keys << sk + end + # Delete unset softkeys + # OPTIMIZE 40 should be enough for 2 modules, but for some reason array is empty o early + max_keys = max_keys + 50 + while @soft_keys.length <= max_keys + @soft_keys << Softkey.new + end + + @key_pos=1 + + #@soft_keys.each do |sk| + + while @key_pos < shift_key_position + + (1..shift_key_position-1).each do |idx| + first_level_keys(idx) + end + end + if @key_pos == shift_key_position + @new_settings << ['function-key-def', shift_key_position, '18'] + @new_settings << ['key-label', shift_key_position, 'Shift'] + @new_settings << ['key-label-unicode', shift_key_position, 'Shift'] + @key_pos = @key_pos+1 + end + + (1001..1000+shift_key_position-1).each do |idx| + second_level_keys(idx) + end + # First key-module first level + (301..311).each do |idx| + first_level_keys(idx) + end + # First key-module shift level + (1301..1311).each do |idx| + second_level_keys(idx) + end + # Second key-module first level + (401..411).each do |idx| + first_level_keys(idx) + end + # Second key-module shift level + (1401..1411).each do |idx| + second_level_keys(idx) + end + [312, 412].each do |idx| + @new_settings << ['function-key-def', idx, '18'] + @new_settings << ['key-label', idx, 'Shift'] + @new_settings << ['key-label-unicode', idx, 'Shift'] + end + #end + logger.debug(@new_settings) + end + + if (@phone.nil? || @sip_account.blank?) && fragment != "final" + @new_settings = Array.new + @my_nonce = params[:WorkpointMessage][:Message][:nonce] + @new_settings << ['e164', nil, 'NULL'] + @new_settings << ['sip-user-id', nil, ""] + @new_settings << ['sip-pwd', nil, ""] + @new_settings << ['sip-name', nil, ""] + @new_settings << ['display-id-unicode', nil, ""] + @new_settings << ['reg-addr', nil, ""] + @new_settings << ['registrar-addr', nil, "NULL"] + @new_settings << ['outbound-proxy-user', nil, ""] + @new_settings << ['sgnl-gateway-addr-user', nil, ""] + @new_settings << ['realm', nil, ""] + @new_settings << ['pickup-group-uri', nil, ""] + logger.debug(@new_settings) + + respond_to { |format| + format.xml { render :action => "write" } + } + elsif contact_reason == 'local-changes' + respond_to { |format| + format.xml { render :action => "clean-up" } + } + elsif (reply_status == 'accepted' && contact_reason == 'reply-to' && reply_action == 'ReadAllItems') + respond_to { |format| + format.xml { render :action => "write" } + } + + elsif ["reply-to"].include? contact_reason + respond_to { |format| + format.xml { render :action => "clean-up" } + } + + else + respond_to { |format| + format.xml { render :action => "index" } + } + end + + end + + def first_level_keys(key_idx) + sk = @soft_keys.shift + if sk.softkey_function + softkey_function = sk.softkey_function.name + end + case softkey_function + when 'blf' + @new_settings << ['function-key-def', key_idx, '59'] + @new_settings << ['stimulus-led-control-uri', key_idx, sk.number ] + @new_settings << ['stimulus-DTMF-sequence', key_idx, sk.number ] + @new_settings << ['blf-popup', key_idx, 'true'] + when 'log_out' + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, 'f-lo' ] + @new_settings << ['stimulus-led-control-uri', key_idx, '' ] + @new_settings << ['stimulus-DTMF-sequence', key_idx, '' ] + when 'log_in' + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, "f-li-#{sk.number}" ] + @new_settings << ['stimulus-led-control-uri', key_idx, '' ] + @new_settings << ['stimulus-DTMF-sequence', key_idx, '' ] + when 'hold' + @new_settings << ['function-key-def', key_idx, '10'] + @new_settings << ['select-dial', key_idx, '' ] + @new_settings << ['stimulus-led-control-uri', key_idx, '' ] + @new_settings << ['stimulus-DTMF-sequence', key_idx, '' ] + when 'dtmf' + @new_settings << ['function-key-def', key_idx, '54'] + @new_settings << ['stimulus-DTMF-sequence', key_idx, sk.number ] + @new_settings << ['stimulus-led-control-uri', key_idx, '' ] + @new_settings << ['stimulus-DTMF-sequence', key_idx, '' ] + when 'call_forwarding' + @new_settings << ['function-key-def', key_idx, '63'] + @new_settings << ['stimulus-led-control-uri', key_idx, "f-cftg-#{sk.call_forward_id}" ] + @new_settings << ['send-url-address', key_idx, request.host] + @new_settings << ['send-url-protocol', key_idx, 3] + @new_settings << ['send-url-port', key_idx, '80'] + @new_settings << ['send-url-path', key_idx, "/config_siemens/#{@phone.id}/#{@sip_account.id}/call_forwarding.xml"] + @new_settings << ['send-url-query', key_idx, "id=#{sk.call_forward_id}&function=toggle"] + @new_settings << ['send-url-method', key_idx, '0'] + @new_settings << ['blf-popup', key_idx, 'false'] + when 'call_forwarding_always' + phone_number = PhoneNumber.where(:number => sk.number, :phone_numberable_type => 'SipAccount').first + if phone_number + account_param = (phone_number.phone_numberable_id != @sip_account.id ? "&account=#{phone_number.phone_numberable_id}" : '') + else + phone_number = @sip_account.phone_numbers.first + account_param = '' + end + + if phone_number + @new_settings << ['function-key-def', key_idx, '63'] + @new_settings << ['stimulus-led-control-uri', key_idx, "f-cfutg-#{phone_number.id}" ] + @new_settings << ['send-url-address', key_idx, request.host] + @new_settings << ['send-url-protocol', key_idx, 3] # 0=https, 3=http + @new_settings << ['send-url-port', key_idx, '80'] + @new_settings << ['send-url-path', key_idx, "/config_siemens/#{@phone.id}/#{@sip_account.id}/call_forwarding.xml"] + @new_settings << ['send-url-query', key_idx, "type=always&function=toggle#{account_param}"] + @new_settings << ['send-url-method', key_idx, '0'] # 0=get, 1=post + # @new_settings << ['send-url-user-id', key_idx, 'user'] + # @new_settings << ['send-url-passwd', key_idx, 'secret'] + @new_settings << ['blf-popup', key_idx, 'false'] + end + when 'call_forwarding_assistant' + phone_number = PhoneNumber.where(:number => sk.number, :phone_numberable_type => 'SipAccount').first + if phone_number + account_param = (phone_number.phone_numberable_id != @sip_account.id ? "&account=#{phone_number.phone_numberable_id}" : '') + else + phone_number = @sip_account.phone_numbers.first + account_param = '' + end + + if phone_number + @new_settings << ['function-key-def', key_idx, '63'] + @new_settings << ['stimulus-led-control-uri', key_idx, "f-cfatg-#{phone_number.id}" ] + @new_settings << ['send-url-address', key_idx, request.host] + @new_settings << ['send-url-protocol', key_idx, 3] # 0=https, 3=http + @new_settings << ['send-url-port', key_idx, '80'] + @new_settings << ['send-url-path', key_idx, "/config_siemens/#{@phone.id}/#{@sip_account.id}/call_forwarding.xml"] + @new_settings << ['send-url-query', key_idx, "type=assistant&function=toggle#{account_param}"] + @new_settings << ['send-url-method', key_idx, '0'] # 0=get, 1=post + @new_settings << ['blf-popup', key_idx, 'false'] + end + when 'hunt_group_membership' + phone_number = PhoneNumber.where(:number => sk.number, :phone_numberable_type => 'HuntGroup').first + if phone_number + hunt_group = HuntGroup.where(:id => phone_number.phone_numberable_id).first + end + + sip_account_phone_numbers = Array.new() + @sip_account.phone_numbers.each do |pn| + sip_account_phone_numbers.push(pn.number) + end + + hunt_group_member_numbers = PhoneNumber.where(:number => sip_account_phone_numbers, :phone_numberable_type => 'HuntGroupMember') + + hunt_group_member = nil + if hunt_group and hunt_group_member_numbers + hunt_group_member_numbers.each do |hunt_group_member_number| + hunt_group_member = hunt_group.hunt_group_members.where(:id => hunt_group_member_number.phone_numberable_id).first + if hunt_group_member + break + end + end + end + + if hunt_group_member + @new_settings << ['function-key-def', key_idx, '63'] + @new_settings << ['stimulus-led-control-uri', key_idx, "f-hgmtg-#{hunt_group_member.id}" ] + @new_settings << ['send-url-address', key_idx, request.host] + @new_settings << ['send-url-protocol', key_idx, 3] # 0=https, 3=http + @new_settings << ['send-url-port', key_idx, '80'] + @new_settings << ['send-url-path', key_idx, "/config_siemens/#{@phone.id}/#{@sip_account.id}/hunt_group.xml"] + @new_settings << ['send-url-query', key_idx, "group=#{hunt_group.id}&account=#{hunt_group_member.id}&function=toggle"] + @new_settings << ['send-url-method', key_idx, '0'] # 0=get, 1=post + @new_settings << ['blf-popup', key_idx, 'false'] + end + when nil + @new_settings << ['function-key-def', key_idx, '0'] + @new_settings << ['stimulus-led-control-uri', key_idx, '' ] + @new_settings << ['stimulus-DTMF-sequence', key_idx, '' ] + else + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, sk.number ] + @new_settings << ['stimulus-led-control-uri', key_idx, '' ] + @new_settings << ['stimulus-DTMF-sequence', key_idx, '' ] + end + @new_settings << ['key-label', key_idx, sk.label ] + @new_settings << ['key-label-unicode', key_idx, sk.label ] + @key_pos = @key_pos+1 + end + + def second_level_keys(key_idx) + sk = @soft_keys.shift + softkey_function = nil + if sk.softkey_function + softkey_function = sk.softkey_function.name + end + case softkey_function + when 'log_out' + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, 'f-lo' ] + when 'log_in' + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, "f-li-#{sk.number}" ] + when 'dtmf' + @new_settings << ['function-key-def', key_idx, '54'] + @new_settings << ['stimulus-DTMF-sequence', key_idx, sk.number ] + when nil + @new_settings << ['function-key-def', key_idx, '0'] + else + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, sk.number ] + end + @new_settings << ['key-label', key_idx, sk.label ] + @new_settings << ['key-label-unicode', key_idx, sk.label ] + @key_pos = @key_pos+1 + end + + def call_history + if ! params[:number].blank? + number = params[:number] + end + + if ! params[:function].blank? + function = params[:function].to_s.downcase + end + + if ! params[:sip_account].blank? + @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first + end + + if ! @sip_account and ! params[:phonenumber].blank? + @sip_account = SipAccount.where(:auth_name => params[:phonenumber]).first + end + + if ! params[:type].blank? + @type = params[:type] + elsif ! params[:tab].blank? + @type = params[:tab].rpartition("_")[2] + end + + if ! ['dialed', 'missed', 'received'].include? @type + @type = 'missed' + end + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" + + @phone_xml_object = { + :name => "menu_list", + :columns => 1, + :url => base_url, + :make_call => (function.to_s == 'dial' ? number.to_s : nil), + :hidden => {:sip_account => @sip_account.id, :type => @type}, + :commands => [{ + :type => 'SELECT', + :label => 'Dial', + :display_on => 'LISTITEM', + :key => 'function', + :value => 'dial', + }], + :entries => [], + } + + if function.to_s == 'clear_notification' + @sip_account.call_histories.update_all({:read_flag => true}) + end + + last_missed_call = @sip_account.call_histories.where(:entry_type => 'missed').order('start_stamp DESC').first + if last_missed_call and !last_missed_call.read_flag + @phone_xml_object[:led] = true + else + @phone_xml_object[:led] = false + end + + calls = @sip_account.call_histories.where(:entry_type => @type).order('start_stamp DESC').limit(MAX_DIRECTORY_ENTRIES) + + if @type == 'missed' && @phone_xml_object[:led] == true + @phone_xml_object[:commands].push({ + :type => 'SELECT', + :label => 'Clear Notification', + :key => 'function', + :value => 'clear_notification', + }) + end + + auto_reload_time = 60 + + SIEMENS_HISTORY_RELOAD_TIMES.each_pair do |time_range, reload_value| + if time_range === Time.now.localtime.hour + auto_reload_time = reload_value + end + end + + @phone_xml_object[:commands].push({ + :type => 'UPDATE', + :auto => auto_reload_time, + :label => 'Update', + }) + + calls.each do |call| + display_name = call.display_name + phone_number = call.display_number + phone_book_entry = call.phone_book_entry_by_number(phone_number) + if display_name.blank? + display_name = phone_book_entry.to_s + end + + @phone_xml_object[:entries].push({ + :selected => false, + :key => 'number', + :value => phone_number, + :text => "#{call_date_compact(call.start_stamp)} #{display_name} #{phone_number}", + }) + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + end + + def call_forwarding + if ! params[:type].blank? + @type = params[:type] + end + + if ! params[:function].blank? + @function = params[:function] + end + + if ! params[:id].blank? + @call_forwarding_id = params[:id].to_i + end + + if ! params[:sip_account].blank? + @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first + end + + if ! params[:account].blank? + @sip_account = SipAccount.where({ :id => params[:account].to_i }).first + end + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + if @function == 'toggle' + if @call_forwarding_id + call_forwarding = @sip_account.call_forwards.where(:id => @call_forwarding_id).first + + if !call_forwarding and @sip_account.softkeys.where(:call_forward_id => @call_forwarding_id).count > 0 + call_forwarding = CallForward.where(:id => @call_forwarding_id).first + end + + if call_forwarding + call_forwarding.toggle + end + elsif @type + call_forwarding = @sip_account.call_forwarding_toggle(@type) + end + if !call_forwarding + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Call forwarding not set: #{@sip_account.errors.messages.inspect} -->", + ) + return + end + + if !call_forwarding.errors.blank? + error_messages = Array.new() + call_forwarding.errors.messages.each_pair do |key, message| + error_messages.push(message.join(';')) + end + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- ERROR #{error_messages.join(',')} #{call_forwarding.to_s}) -->", + ) + elsif call_forwarding.active + render( + :status => 200, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- ON #{call_forwarding.to_s} -->", + ) + else + render( + :status => 200, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- OFF #{call_forwarding.to_s} -->", + ) + end + return + end + + base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" + + @phone_xml_object = { + :name => "number_list", + :columns => 1, + :url => base_url, + :hidden => {:sip_account => @sip_account.id, :type => @type}, + :entries => [] + } + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render + } + } + end + + + def hunt_group + if ! params[:goto].blank? + redirect_to params[:goto] + return; + end + + if ! params[:function].blank? + @function = params[:function] + end + + if ! params[:group].blank? + @hunt_group = HuntGroup.where({ :id => params[:group].to_i }).first + end + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + if ! params[:account].blank? + hunt_group_member = @hunt_group.hunt_group_members.where({ :id => params[:account].to_i }).first + end + + base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" + + if @function == 'toggle' + if ! hunt_group_member + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- HuntGroupMember not found -->", + ) + return + end + + if hunt_group_member.can_switch_status_itself == true + if hunt_group_member.active + hunt_group_member.active = false + else + hunt_group_member.active = true + end + + if ! hunt_group_member.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{hunt_group_member.errors.inspect} -->", + ) + else + render( + :status => 200, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Member #{hunt_group_member.id} toggled -->", + ) + end + return + end + elsif @function == 'members' + commands = [{ + :type => 'UPDATE', + :auto => 20, + :label => 'Update', + },{ + :type => 'BACK', + :label => 'Back', + :display_on => 'OPTIONS', + },{ + :type => 'EXIT', + :label => 'Exit', + :display_on => 'OPTIONS', + },{ + :type => 'SELECT', + :label => 'Show', + :display_on => 'LISTITEM', + }] + + @phone_xml_object = { + :name => "menu_list", + :columns => 1, + :url => base_url, + :hidden => {:function => @function, :group => @hunt_group.id}, + :entries => [], + :commands => commands, + } + + @hunt_group.hunt_group_members.where(:active => true).each do |member| + @phone_xml_object[:entries].push({ + :selected => false, + :value => member.id, + :text => member.name, + }) + end + else + hunt_groups = Array.new() + phone_numbers = Array.new() + @sip_account.phone_numbers.each do |phone_number| + phone_numbers.push(phone_number.number) + assistant_call_forwardings = phone_number.call_forwards.where(:call_forward_case_id => CallForwardCase.where(:value => 'assistant').first.id) + assistant_call_forwardings.each do |assistant_call_forwarding| + if assistant_call_forwarding.call_forwardable_type == 'HuntGroup' && assistant_call_forwarding.call_forwardable_id.to_i > 0 + hunt_groups.push(assistant_call_forwarding.call_forwardable_id.to_i) + end + end + end + + hunt_group_members = Array.new() + if phone_numbers.length > 0 + hunt_group_members = PhoneNumber.where(:phone_numberable_type => 'HuntGroupMember', :number => phone_numbers) + end + + hunt_group_members.each do |hunt_group| + hunt_groups.push(hunt_group.phone_numberable.hunt_group_id) + end + + hunt_groups = HuntGroup.where(:id => hunt_groups) + + @phone_xml_object = { + :name => "menu_list", + :columns => 1, + :url => base_url, + :hidden => {:function => 'members'}, + :entries => [], + :commands => [{ + :type => 'EXIT', + :label => 'Exit', + :display_on => 'OPTIONS', + },{ + :type => 'BACK', + :label => 'Back', + :display_on => 'OPTIONS', + },{ + :type => 'SELECT', + :label => 'Select', + :display_on => 'LISTITEM', + }], + } + + hunt_groups.each do |hunt_group| + @phone_xml_object[:entries].push({ + :selected => false, + :key => 'group', + :value => hunt_group.id, + :text => hunt_group.name, + }) + end + + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + end + + + def menu + if ! @phone or ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Phone or SipAccount not found -->", + ) + return + end + + type = 'menu' + if ! params[:type].blank? + type = params[:type] + elsif ! params[:tab].blank? + tab = params[:tab].rpartition("_") + if tab[1] != '' + type = tab[2] + end + end + + if ! params[:item].blank? + item = params[:item] + end + + menu_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" + base_url = "#{request.protocol}#{request.host_with_port}/config_siemens/#{@phone.id}" + + @phone_xml_object = { + :name => "menu_list", + :columns => 1, + :url => menu_url, + :hidden => {:type => type}, + :entries => [] + } + + case type + when 'menu' + items = [ + { + :value => 'phone_directory', + :text => "Directory", + :url => "#{menu_url}?type=#{type}", + },{ + :value => 'call_history', + :text => "Call History", + :url => "#{menu_url}?type=call_history", + }, + ] + when 'status' + items = [ + { + :value => 'hunt_group', + :text => "Hunt Group", + :url => "#{base_url}/hunt_group.xml" + }, + ] + + commands = [ + { + :type => 'UPDATE', + :auto => 10, + :label => 'Update', + } + ] + when 'help' + items = [ + { + :key => 'item', + :value => 'help', + :text => "Help", + :url => "#{menu_url}?type=#{type}", + }, + ] + when 'call_history' + items = [ + { + :value => 'missed', + :text => "Missed", + :url => "#{base_url}/call_history.xml?type=missed", + },{ + :value => 'dialed', + :text => "Dialed", + :url => "#{base_url}/call_history.xml?type=dialed", + },{ + :value => 'received', + :text => "Received", + :url => "#{base_url}/call_history.xml?type=received", + }, + ] + end + + if item + items.each do |entry| + if entry[:value] == item + redirect_to entry[:url] + return; + end + end + end + + @phone_xml_object[:entries] = items + @phone_xml_object[:commands] = commands + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + end + + def call_date_compact(date) + if date.strftime('%Y%m%d') == DateTime::now.strftime('%Y%m%d') + return date.strftime('%H:%M') + end + return date.strftime('%d.%m %H:%M') + end +end diff --git a/app/controllers/config_siemens_sort_controller.rb b/app/controllers/config_siemens_sort_controller.rb new file mode 100644 index 0000000..c0739e5 --- /dev/null +++ b/app/controllers/config_siemens_sort_controller.rb @@ -0,0 +1,371 @@ +require 'nokogiri' +#doc.search('Message/ItemList').each do |a| puts a.children end +class ConfigSiemensController < ApplicationController +#TODO Authentication + # No access for admins though as this contains personal data. + + # We can't use load_and_authorize_resource() here because + # ConfigSiemensController isn't a resource. + # We can try client certificates + + skip_authorization_check + + + def index + os40_keys=7 + os60_keys=8 + os80_keys=9 + doc = Nokogiri::XML(request.body.read) + #logger.debug("#{params[:WorkpointMessage].to_xml}") + #logger.debug("#{params[:WorkpointMessage][:Message][:ItemList].to_xml}") + @phone_items=Hash.new + contact_reason = params[:WorkpointMessage][:Message][:ReasonForContact] + reply_status = doc.search('Message/ReasonForContact').first[:status] + reply_action = doc.search('Message/ReasonForContact').first[:action] + + doc.search('Message/ItemList/Item').each do |post_item| + @phone_items[post_item[:name]]=post_item.children.to_s + end + + mac_address = @phone_items['mac-addr'] + phone_type = @phone_items['device-type'] + if phone_type == "OpenStage 40" + max_keys = (os40_keys) * 2 + elsif phone_type == "OpenStage 60" + max_keys = (os60_keys) * 2 + elsif phone_type == "OpenStage 80" + max_keys = (os80_keys) * 2 + else + max_keys = 0 + end + + blf_keys_max = max_keys / 2 + shift_key_position = blf_keys_max - 1 + + #logger.debug(request.body.read) + @phone = Phone.find_by_mac_address(mac_address.gsub(':','').upcase) + if ! @phone.nil? + @phone.update_attributes(:ip_address => request.remote_ip) + sip_account = SipAccount.where(:sip_accountable_type == @phone.phoneable_type, + :sip_accountable_id == @phone.phoneable_id).first + end + + if ! @phone.nil? && ! sip_account.nil? + #logger.debug(@phone_items) + @my_nonce = params[:WorkpointMessage][:Message][:nonce] + @new_settings = Array.new + + @new_settings << ['dhcp', nil, 'true'] + @new_settings << ['hostname', nil, mac_address.gsub(':', '') ] + @new_settings << ['e164-hostname', nil, 'false'] + @new_settings << ['mobility-enabled', nil, 'false'] + @new_settings << ['mobility-password-on-logoff', nil, 'false'] + @new_settings << ['e164', nil, sip_account.try(:phone_numbers).first.number] + @new_settings << ['sip-user-id', nil, sip_account.auth_name] + @new_settings << ['reg-id', nil, sip_account.auth_name] + @new_settings << ['reg-number', nil, sip_account.auth_name] + @new_settings << ['fully-qualified-phone-no', nil, sip_account.auth_name] + @new_settings << ['sip-pwd', nil, sip_account.password] + @new_settings << ['sip-name', nil, sip_account.caller_name] + @new_settings << ['register-by-name', nil, 'false'] + #OPTIMIZE Display ID ? + @new_settings << ['display-id', nil, sip_account.try(:phone_numbers).first.number] + @new_settings << ['display-id-unicode', nil, sip_account.caller_name] + @new_settings << ['use-display-id', nil, 'true'] + @new_settings << ['reg-addr', nil, sip_account.sip_domain.host] + @new_settings << ['reg-port', nil, '5060'] + @new_settings << ['registrar-addr', nil, sip_account.sip_domain.host] + @new_settings << ['registrar-port', nil, '5060'] + @new_settings << ['outbound-proxy', nil, sip_account.sip_domain.host] + @new_settings << ['outbound-proxy-user', nil, sip_account.sip_domain.host] + @new_settings << ['sgnl-gateway-addr', nil, sip_account.sip_domain.host] + @new_settings << ['sgnl-gateway-addr-user', nil, sip_account.sip_domain.host] + @new_settings << ['sgnl-gateway-port', nil, '5060' ] + @new_settings << ['sgnl-gateway-port-user', nil, '5060'] + @new_settings << ['sgnl-route', nil, '0' ] + @new_settings << ['mwi-e164', nil, '' ] + @new_settings << ['rtp-base-port', nil, '5004'] + @new_settings << ['default-domain', nil, '' ] + @new_settings << ['sip-transport', nil, '0' ] + @new_settings << ['sip-transport-user', nil, '0' ] + @new_settings << ['server-type', nil, '0' ] + @new_settings << ['session-timer', nil, 'true'] + @new_settings << ['session-duration', nil, '3600' ] + @new_settings << ['reg-ttl', nil, '3600' ] + @new_settings << ['realm', nil, sip_account.sip_domain.realm] + @new_settings << ['emergency-e164', nil, '0110' ] + @new_settings << ['voice-mail-e164', nil, 'voicemail'] + @new_settings << ['auto-answer', nil, 'false'] + @new_settings << ['beep-on-auto-answer', nil, 'true'] + @new_settings << ['auto-reconnect', nil, 'false' ] + @new_settings << ['beep-on-auto-reconnect', nil, 'true'] + @new_settings << ['permit-decline-call', nil, 'true'] + @new_settings << ['transfer-on-ring', nil, 'false' ] + @new_settings << ['join-allowed-in-conference', nil, 'true'] + @new_settings << ['pickup-group-uri', nil, '*8*'] + @new_settings << ['pickup-group-uri', nil, '' ] + @new_settings << ['hot-line-warm-line-digits', nil, '' ] + @new_settings << ['initial-digit-timer', nil, '30' ] + @new_settings << ['conference-factory-uri', nil, ''] + @new_settings << ['callback-busy-allow', nil, 'false'] + @new_settings << ['callback-busy-code', nil, '' ] + @new_settings << ['callback-ring-allow', nil, 'false'] + @new_settings << ['callback-ring-code', nil, ''] + @new_settings << ['callback-cancel-code', nil, ''] + @new_settings << ['park-server', nil, ''] + #OPTIMIZE Callwaiting + @new_settings << ['call-waiting-enabled', nil, 'true'] + @new_settings << ['qos-layer2', nil, 'true'] + @new_settings << ['l2qos-voice', nil, '5' ] + @new_settings << ['l2qos-signalling', nil, '3' ] + @new_settings << ['l2qos-default', nil, '0'] + @new_settings << ['qos-layer3', nil, 'true'] + @new_settings << ['l3qos-voice', nil, '46'] + @new_settings << ['l3qos-signalling', nil, '26'] + @new_settings << ['vlan-method', nil, '1'] + #OPTIMIZE Timezone + @new_settings << ['sntp-tz-offset', nil, ''] + @new_settings << ['daylight-save', nil, ''] + @new_settings << ['daylight-save-minutes', nil, ''] + #OPTIMIZE Use SNMP? + @new_settings << ['snmp-trap-addr', nil, ''] + @new_settings << ['snmp-trap-port', nil, ''] + @new_settings << ['snmp-trap-pwd', nil, 'snmp' ] + @new_settings << ['snmp-traps-active', nil, 'false' ] + @new_settings << ['diagnostic-trap-addr', nil, ''] + @new_settings << ['diagnostic-trap-port', nil, ''] + @new_settings << ['diagnostic-trap-pwd', nil, 'snmp' ] + @new_settings << ['diagnostic-traps-active', nil, 'false' ] + @new_settings << ['diagnostic-snmp-active', nil, 'false'] + @new_settings << ['qdc-collection-unit-addr', nil, ''] + @new_settings << ['qdc-collection-unit-port', nil, '12010'] + + @new_settings << ['qdc-trap-pwd', nil, 'QOSDC'] + @new_settings << ['qdc-snmp-active', nil, 'false'] + @new_settings << ['qdc-qcu-active', nil, 'false'] + @new_settings << ['snmp-queries-allowed', nil, 'false'] + @new_settings << ['snmp-pwd', nil, ''] + @new_settings << ['disable-microphone', nil, 'false'] + @new_settings << ['loudspeech-enabled', nil, 'true'] + @new_settings << ['audio-silence-suppression', nil, 'false'] + + @new_settings << ['port1', nil, '0' ] # 0=Automatic (speed) + @new_settings << ['port2', nil, '0' ] + @new_settings << ['port2-mode', nil, '1' ] + @new_settings << ['port2-auto-mdix-enabled', nil, 'true' ] + @new_settings << ['originating-line-preference', nil, '0'] + @new_settings << ['terminating-line-preference', nil, '0'] + @new_settings << ['line-key-operating-mode', nil, '0'] + @new_settings << ['line-rollover-type', nil, '2'] + @new_settings << ['line-rollover-volume', nil, '5' ]# 1-5 + @new_settings << ['line-registration-leds', nil, 'true'] + @new_settings << ['keyset-use-focus', nil, 'true' ] + @new_settings << ['keyset-remote-forward-ind', nil, 'true'] + @new_settings << ['keyset-reservation-timer', nil, '60' ] # 0-300 + @new_settings << ['dial-plan-enabled', nil, '' ] + @new_settings << ['Canonical-dialing-international-prefix', nil, ''] + @new_settings << ['Canonical-dialing-local-country-code', nil, ''] + @new_settings << ['Canonical-dialing-national-prefix', nil, ''] + @new_settings << ['Canonical-dialing-local-area-code', nil, ''] + @new_settings << ['Canonical-dialing-local-node', nil, ''] + @new_settings << ['Canonical-dialing-external-access', nil, '0'] + @new_settings << ['Canonical-dialing-operator-code', nil, ''] + @new_settings << ['Canonical-dialing-emergency-number', nil, ''] + @new_settings << ['Canonical-dialing-dial-needs-access-code', nil, '0'] + @new_settings << ['Canonical-dialing-dial-needs-intGWcode', nil, '0'] + @new_settings << ['Canonical-dialing-min-local-number-length', nil, '10'] + @new_settings << ['Canonical-dialing-extension-initial-digits', nil, ''] + @new_settings << ['Canonical-dialing-dial-internal-form', nil, '0' ] + @new_settings << ['Canonical-dialing-dial-external-form', nil, '0' ] + @new_settings << ['Canonical-lookup-local-code', nil, '' ] + @new_settings << ['Canonical-lookup-international-code', nil, ''] + @new_settings << ['hot-keypad-dialing', nil, ''] + @new_settings << ['ldap-transport', nil, '0'] + @new_settings << ['ldap-server-address', nil, '' ] + @new_settings << ['ldap-server-port', nil, '389' ] + @new_settings << ['ldap-authentication', nil, '1'] + @new_settings << ['ldap-user', nil, '' ] + @new_settings << ['ldap-pwd', nil, '' ] + @new_settings << ['ldap-max-responses', nil, '25'] + @new_settings << ['backup-addr', nil, ''] + @new_settings << ['backup-registration', nil, 'false'] + @new_settings << ['qdc-qcu-active', nil, 'false' ] + @new_settings << ['min-admin-passw-length', nil, '6' ] + @new_settings << ['default-locked-config-menus', nil, 'true' ] + @new_settings << ['locked-config-menus', nil, 'true' ] + @new_settings << ['default-locked-local-function-menus', nil, 'true' ] + @new_settings << ['locked-local-function-menus', nil, 'true' ] + @new_settings << ['dls-mode-secure', nil, '0' ] + @new_settings << ['dls-chunk-size', nil, '9492'] + @new_settings << ['default-passw-policy', nil, 'false'] + @new_settings << ['deflect-destination', nil, ''] + @new_settings << ['display-skin', nil, ''] + @new_settings << ['enable-bluetooth-interface', nil, 'true'] + @new_settings << ['usb-access-enabled', nil, 'false' ] + @new_settings << ['usb-backup-enabled', nil, 'false' ] + @new_settings << ['line-button-mode', nil, '0' ] + @new_settings << ['lock-forwarding', nil, '' ] + @new_settings << ['loudspeaker-function-mode', nil, '0' ] + @new_settings << ['max-pin-retries', nil, '' ] + @new_settings << ['inactivity-timeout', nil, '30' ] + @new_settings << ['not-used-timeout', nil, '2' ] + @new_settings << ['passw-char-set', nil, '0' ] + @new_settings << ['refuse-call', nil, 'true' ] + @new_settings << ['restart-password', nil, ''] + #OPTIMIZE clock format + @new_settings << ['time-format', nil, '0' ]# 1=12 h + @new_settings << ['uaCSTA-enabled', nil, 'false' ] + @new_settings << ['enable-test-interface', nil, 'false'] + @new_settings << ['enable-WBM', nil, 'true'] + @new_settings << ['pixelsaver-timeout', nil, '2' ]# 2 hours? + @new_settings << ['voice-message-dial-tone', nil, '' ] + @new_settings << ['call-pickup-allowed', nil, 'true' ] + @new_settings << ['group-pickup-tone-allowed', nil, 'true'] + @new_settings << ['group-pickup-as-ringer', nil, 'false'] + @new_settings << ['group-pickup-alert-type', nil, '0' ] + @new_settings << ['default-profile', nil, '' ] + @new_settings << ['count-medium-priority', nil, '5'] + @new_settings << ['timer-medium-priority', nil, '60'] # 1 - 999 + @new_settings << ['timer-high-priority', nil, '5'] # 0 - 999 + @new_settings << ['dss-sip-detect-timer', nil, '10'] + @new_settings << ['dss-sip-deflect', nil, 'false' ] + @new_settings << ['dss-sip-refuse', nil, 'false' ] + @new_settings << ['feature-availability', nil, 'false'] + @new_settings << ['feature-availability', nil, 'true' ] + @new_settings << ['feature-availability', nil, 'true' ] + @new_settings << ['local-control-feature-availability', nil, 'false' ] + @new_settings << ['trace-level', nil, '0' ] # Off + @new_settings << ['default-locked-function-keys', nil, 'true' ]# "unknown item" + #OPTIMIZE Put pickup prefix into database/global constant? + @new_settings << ['blf-code', nil, 'f_ia_'] # pickup prefix for softkey function 59 (BLF) + @new_settings << ['stimulus-feature-code', nil, true] + @new_settings << ['stimulus-led-control-uri', nil, true] + + + @new_settings << ['min-user-passw-length', nil, '6' ]# 6 - 24 + #OPTIMIZE language + @new_settings << ['country-iso', nil, 'DE' ] + @new_settings << ['language-iso', nil, 'de'] + @new_settings << ['date-format', nil, '0' ] # DD.MM.YYYY + #OPTIMIZE ringtones + @new_settings << ['ringer-melody', nil, '1'] + + @new_settings << ['ringer-melody', nil, '2'] + @new_settings << ['ringer-tone-sequence', nil, '2'] + + soft_keys = Array.new + # Getting BLF keys only for the first level + blf_keys = sip_account.softkeys.find( + :all, + :conditions => {:function => ['blf', 'conference']}, + :limit => blf_keys_max) + #Getting other keys + non_blf_keys = sip_account.softkeys.find( + :all, + :conditions => {:function => ['speed_dial']}) + + # Fill softkey array with BLF keys up to shift key + blf_keys.each do |k| + soft_keys << k + end + # Fill sofkey with other keys up to end + non_blf_keys.each do |k| + if soft_keys.length < max_keys + soft_keys << k + end + end + # Delete unset softkeys + while soft_keys.length < max_keys + soft_keys << Softkey.new + end + + key_pos=1 + + #soft_keys.each do |sk| + + while key_pos < shift_key_position + + (1..shift_key_position-1).each do |key_idx| + sk = soft_keys.shift + logger.debug(sk.function, key_idx) + if sk.function == "blf" + @new_settings << ['function-key-def', key_idx, '59'] + @new_settings << ['select-dial', key_idx, sk.number ] + elsif sk.function == "log_out" + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, 'f_lo' ] + elsif sk.function == "log_in" + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, "f_li_#{sk.number}" ] + elsif sk.function == "dtmf" + @new_settings << ['function-key-def', key_idx, '54'] + @new_settings << ['stimulus-DTMF-sequence', key_idx, sk.number ] + elsif sk.function.nil? + @new_settings << ['function-key-def', key_idx, '0'] + else + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, sk.number ] + end + @new_settings << ['key-label', key_idx, sk.label ] + @new_settings << ['key-label-unicode', key_idx, sk.label ] + key_pos = key_pos+1 + + end + end + if key_pos == shift_key_position + @new_settings << ['function-key-def', shift_key_position, '18'] + @new_settings << ['key-label', shift_key_position, 'Shift'] + @new_settings << ['key-label-unicode', shift_key_position, 'Shift'] + key_pos = key_pos+1 + end + + (1001..1000+shift_key_position-1).each do |key_idx| + sk = soft_keys.shift + if sk.function == "log_out" + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, 'f_lo' ] + elsif sk.function == "log_in" + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, "f_li_#{sk.number}" ] + elsif sk.function == "dtmf" + @new_settings << ['function-key-def', key_idx, '54'] + @new_settings << ['stimulus-DTMF-sequence', key_idx, sk.number ] + elsif sk.function.nil? + @new_settings << ['function-key-def', key_idx, '0'] + else + @new_settings << ['function-key-def', key_idx, '1'] + @new_settings << ['select-dial', key_idx, sk.number ] + end + @new_settings << ['key-label', key_idx, sk.label ] + @new_settings << ['key-label-unicode', key_idx, sk.label ] + key_pos = key_pos+1 + + end + + #end + logger.debug(@new_settings) + end + + if @phone.nil? || sip_account.nil? + respond_to { |format| + format.xml { render :action => "clean-up" } + } + + elsif (reply_status == 'accepted' && contact_reason == 'reply-to' && reply_action == 'ReadAllItems') + respond_to { |format| + format.xml { render :action => "write" } + } + + elsif ["reply-to"].include? contact_reason + respond_to { |format| + format.xml { render :action => "clean-up" } + } + + else + respond_to { |format| + format.xml { render :action => "index" } + } + end + + end +end diff --git a/app/controllers/config_snom_controller.rb b/app/controllers/config_snom_controller.rb new file mode 100644 index 0000000..40f0c4e --- /dev/null +++ b/app/controllers/config_snom_controller.rb @@ -0,0 +1,1169 @@ +class ConfigSnomController < ApplicationController + MAX_SIP_ACCOUNTS_COUNT = 11 + MAX_SOFTKEYS_COUNT = 12 + (42 * 3) - 1 + MAX_DIRECTORY_ENTRIES = 20 + KEYPAD_TO_CHAR = { + '0' => [' ','-','.',',','0'], + '1' => [' ','-','.',',','1'], + '2' => ['a','b','c','2'], + '3' => ['d','e','f','3'], + '4' => ['g','h','i','4'], + '5' => ['j','k','l','5'], + '6' => ['m','n','o','6'], + '7' => ['p','q','r','s','7'], + '8' => ['t','u','v','8'], + '9' => ['w','x','y','z','9'], + } + + skip_authorization_check + + before_filter { |controller| + @mac_address = params[:mac_address].to_s.upcase.gsub(/[^0-9A-F]/,'') + @provisioning_authenticated = false + + if !params[:provisioning_key].blank? + @phone = Phone.where({ :provisioning_key => params[:provisioning_key] }).first + if @phone + @provisioning_authenticated = true + @mac_address = @phone.mac_address + end + end + + if ! @mac_address.blank? then + if !@phone + @phone = Phone.where({ :mac_address => @mac_address }).first + end + + if ! @phone && PROVISIONING_AUTO_ADD_PHONE + tenant = Tenant.where(:id => PROVISIONING_AUTO_TENANT_ID).first + if ! tenant + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Tenant not found -->", + ) + return + end + + @phone = tenant.phones.build + @phone.mac_address = @mac_address + @phone.hot_deskable = true + + mac_address_to_model = { + '00041325' => 'Snom 300', + '00041328' => 'Snom 300', + '0004132D' => 'Snom 300', + '0004132F' => 'Snom 300', + '00041334' => 'Snom 300', + '00041350' => 'Snom 300', + '0004133B' => 'Snom 300', + '00041337' => 'Snom 300', + '00041324' => 'Snom 320', + '00041327' => 'Snom 320', + '0004132C' => 'Snom 320', + '00041331' => 'Snom 320', + '00041335' => 'Snom 320', + '00041338' => 'Snom 320', + '00041351' => 'Snom 320', + '00041323' => 'Snom 360', + '00041329' => 'Snom 360', + '0004132B' => 'Snom 360', + '00041339' => 'Snom 360', + '00041390' => 'Snom 360', + '00041326' => 'Snom 370', + '0004132E' => 'Snom 370', + '0004133A' => 'Snom 370', + '00041352' => 'Snom 370', + '00041340' => 'Snom 820', + '00041345' => 'Snom 821', + '00041348' => 'Snom 821', + '00041341' => 'Snom 870', + } + + @phone.phone_model = PhoneModel.where(:name => mac_address_to_model[@mac_address[0, 8]]).first + if ! @phone.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{@phone.errors.messages.inspect} -->", + ) + return + end + + if ! PROVISIONING_AUTO_ADD_SIP_ACCOUNT + return + end + + caller_name_index = 0 + sip_account_last = tenant.sip_accounts.where('caller_name LIKE ?', "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}%").sort { |item1, item2| + item1.caller_name.gsub(/[^0-9]/, '').to_i <=> item2.caller_name.gsub(/[^0-9]/, '').to_i + }.last + + if sip_account_last + caller_name_index = sip_account_last.caller_name.gsub(/[^0-9]/, '').to_i + end + caller_name_index = caller_name_index + 1 + + @sip_account = tenant.sip_accounts.build + @sip_account.caller_name = "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}#{caller_name_index}" + @sip_account.call_waiting = CALL_WAITING + @sip_account.clir = DEFAULT_CLIR_SETTING + @sip_account.clip = DEFAULT_CLIP_SETTING + @sip_account.voicemail_pin = random_pin + @sip_account.callforward_rules_act_per_sip_account = CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT + @sip_account.hotdeskable = false + loop do + @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME) + break unless SipAccount.exists?(:auth_name => @sip_account.auth_name) + end + @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD) + + if ! @sip_account.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{@sip_account.errors.messages.inspect} -->", + ) + return + end + + phone_sip_account = PhoneSipAccount.new() + phone_sip_account.phone_id = @phone.id + phone_sip_account.sip_account_id = @sip_account.id + + if ! phone_sip_account.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{phone_sip_account.errors.messages.inspect} -->", + ) + return + end + + end + elsif ! params[:phone].blank? then + @phone = Phone.where({ :id => params[:phone].to_i }).first + end + + if ! @phone + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Phone not found -->", + ) + end + + if ! params[:sip_account].blank? + @sip_account = @phone.sip_accounts.where({ :id => params[:sip_account].to_i }).first + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + end + end + + if ! params[:type].blank? + @type = params[:type].to_s.strip.downcase + end + + if ! params[:keys].blank? + @dialpad_keys = params[:keys].to_s.strip + end + } + + + def show + send_sensitve = @provisioning_authenticated || !@phone.provisioning_key_active + @phone_settings = Hash.new() + + if defined?(PROVISIONING_KEY_LENGTH) && PROVISIONING_KEY_LENGTH > 0 + if @phone.provisioning_key.blank? + @phone.update_attributes({ :provisioning_key => SecureRandom.hex(PROVISIONING_KEY_LENGTH), :provisioning_key_active => false }) + elsif @provisioning_authenticated + @phone.update_attributes({ :provisioning_key_active => true }) + end + + if send_sensitve + if defined?(PROVISIONING_PROTOCOL) && PROVISIONING_PROTOCOL + provisioning_protocol = PROVISIONING_PROTOCOL + else + provisioning_protocol = request.protocol + end + @phone_settings[:setting_server] = "#{provisioning_protocol}#{request.host_with_port}/snom-#{@phone.provisioning_key}.xml" + end + end + + if defined?(PROVISIONING_SET_HTTP_USER) && @phone.http_user.blank? + if PROVISIONING_SET_HTTP_USER.class == Fixnum + @phone.update_attributes({ :http_user => SecureRandom.hex(PROVISIONING_SET_HTTP_USER) }) + elsif PROVISIONING_SET_HTTP_USER.class == String + @phone.update_attributes({ :http_user => PROVISIONING_SET_HTTP_USER }) + end + end + + if defined?(PROVISIONING_SET_HTTP_PASSWORD) && @phone.http_password.blank? + if PROVISIONING_SET_HTTP_PASSWORD.class == Fixnum + @phone.update_attributes({ :http_password => SecureRandom.hex(PROVISIONING_SET_HTTP_PASSWORD) }) + elsif PROVISIONING_SET_HTTP_PASSWORD.class == String + @phone.update_attributes({ :http_password => PROVISIONING_SET_HTTP_PASSWORD }) + end + end + + if send_sensitve + @phone_settings[:http_user] = @phone.http_user + @phone_settings[:http_pass] = @phone.http_password + if defined?(PROVISIONING_ADMIN_PASSWORD) + if PROVISIONING_ADMIN_PASSWORD.class == TrueClass + @phone_settings[:admin_mode_password] = @phone.http_password + elsif PROVISIONING_ADMIN_PASSWORD.class == String + @phone_settings[:admin_mode_password] = PROVISIONING_ADMIN_PASSWORD + end + end + end + + if ! request.env['HTTP_USER_AGENT'].index('snom') + Rails.logger.info "---> User-Agent indicates not a Snom phone (#{request.env['HTTP_USER_AGENT'].inspect})" + else + Rails.logger.info "---> Phone #{@mac_address.inspect}, IP address #{request.remote_ip.inspect}" + @phone.update_attributes({ :ip_address => request.remote_ip }) + end + + @softkeys = Array.new() + @sip_accounts = Array.new() + + if send_sensitve + @phone.sip_accounts.each do |sip_account| + if (sip_account.sip_accountable_type == @phone.phoneable_type) and (sip_account.sip_accountable_id == @phone.phoneable_id) + snom_sip_account = { + :id => sip_account.id, + :active => 'on', + :pname => sip_account.auth_name, + :pass => sip_account.password, + :host => sip_account.host, + :outbound => sip_account.host, + :name => sip_account.auth_name, + :realname => 'Call', + :idle_text => sip_account.caller_name, + :mailbox => "<sip:#{sip_account.auth_name}@#{sip_account.host}>" + } + @sip_accounts.push(snom_sip_account) + sip_account_index = @sip_accounts.length + sip_account.softkeys.order(:position).each do |softkey| + if softkey.softkey_function + softkey_function = softkey.softkey_function.name + end + case softkey_function + when 'blf' + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "blf <sip:#{softkey.number}@#{sip_account.host}>|f-ia-"}) + when 'speed_dial' + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed #{softkey.number}"}) + when 'dtmf' + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "dtmf #{softkey.number}"}) + when 'log_out' + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed f-lo"}) + when 'log_in' + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed f-li-#{softkey.number}"}) + when 'conference' + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "blf <sip:#{softkey.number}@#{sip_account.host}>|f-ta-"}) + when 'call_forwarding' + @softkeys.push({ + :context => sip_account_index, + :function => softkey.function, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "f-cftg-#{softkey.call_forward_id}@#{sip_account.host}", + :for => "#{sip_account.auth_name}@#{sip_account.host}" + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?id=#{softkey.call_forward_id}&function=toggle", + :when => 'on press', + }], + }) + when 'call_forwarding_always' + phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first + if phone_number + account_param = (phone_number.phone_numberable_id != snom_sip_account[:id] ? "&account=#{phone_number.phone_numberable_id}" : '') + else + phone_number = sip_account.phone_numbers.first + account_param = '' + end + + @softkeys.push({ + :context => sip_account_index, + :function => softkey.function, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "f-cfutg-#{phone_number.id}@#{sip_account.host}", + :for => "#{sip_account.auth_name}@#{sip_account.host}" + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?type=always&function=toggle#{account_param}", + :when => 'on press', + }], + }) + when 'call_forwarding_assistant' + phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first + if phone_number + account_param = (phone_number.phone_numberable_id != snom_sip_account[:id] ? "&account=#{phone_number.phone_numberable_id}" : '') + else + phone_number = sip_account.phone_numbers.first + account_param = '' + end + + @softkeys.push({ + :context => sip_account_index, + :function => softkey.function, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "f-cfatg-#{phone_number.id}@#{sip_account.host}", + :for => "#{sip_account.auth_name}@#{sip_account.host}" + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?type=assistant&function=toggle#{account_param}", + :when => 'on press', + }], + }) + when 'hunt_group_membership' + phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'HuntGroup').first + if phone_number + hunt_group = HuntGroup.where(:id => phone_number.phone_numberable_id).first + end + + sip_account_phone_numbers = Array.new() + SipAccount.where(:id => @sip_accounts.first[:id]).first.phone_numbers.each do |phone_number| + sip_account_phone_numbers.push(phone_number.number) + end + + hunt_group_member_numbers = PhoneNumber.where(:number => sip_account_phone_numbers, :phone_numberable_type => 'HuntGroupMember') + + hunt_group_member = nil + if hunt_group and hunt_group_member_numbers + hunt_group_member_numbers.each do |hunt_group_member_number| + hunt_group_member = hunt_group.hunt_group_members.where(:id => hunt_group_member_number.phone_numberable_id).first + if hunt_group_member + break + end + end + end + + if hunt_group_member + @softkeys.push({ + :context => sip_account_index, + :function => softkey.function, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "f-hgmtg-#{hunt_group_member.id}@#{sip_account.host}", + :for => "#{sip_account.auth_name}@#{sip_account.host}" + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/hunt_group.xml?group=#{hunt_group.id}&account=#{hunt_group_member.id}&function=toggle", + :when => 'on press', + }], + }) + else + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => 'none'}) + end + when 'acd_membership' + acd_agent = nil + phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'AutomaticCallDistributor').first + if phone_number + acd = AutomaticCallDistributor.where(:id => phone_number.phone_numberable_id).first + if acd + acd_agent = acd.acd_agents.where(:destination_type => 'SipAccount', :destination_id => sip_account.id).first + end + end + + if acd_agent + @softkeys.push({ + :context => sip_account_index, + :function => softkey.function, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "f-acdmtg-#{acd_agent.id}@#{sip_account.host}", + :for => "#{sip_account.auth_name}@#{sip_account.host}" + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/acd.xml?acd=#{acd.id}&agent=#{acd_agent.id}&function=toggle", + :when => 'on press', + }], + }) + else + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => 'none'}) + end + when 'hold' + @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "keyevent F_R"}) + else + @softkeys.push({:label => softkey.label, :data => 'none'}) + end + end + end + end + end + + languages_map = { + 'ca' => 'Catalan', + 'bs' => 'Bosanski', + 'da' => 'Dansk', + 'de' => 'Deutsch', + 'cs' => 'Cestina', + 'en' => 'English', + 'es' => 'Espanol', + 'fi' => 'Suomi', + 'et' => 'Estonian', + 'fr' => 'Francais', + 'he' => 'Hebrew', + 'hu' => 'Hungarian', + 'it' => 'Italiano', + 'nl' => 'Dutch', + 'no' => 'Norsk', + 'pl' => 'Polski', + 'pt' => 'Portugues', + 'si' => 'Slovenian', + 'sk' => 'Slovencina', + 'ru' => 'Russian', + 'sv' => 'Svenska', + 'tr' => 'Turkce', + } + + tone_schemes_map = { + '1' => 'USA', # United States + '61' => 'AUS', # Australia + '43' => 'AUT', # Austria + '86' => 'CHN', # China + '45' => 'DNK', # Denmark + '33' => 'FRA', # France + '49' => 'GER', # Germany + '44' => 'GBR', # Great Britain + '91' => 'IND', # India + '39' => 'ITA', # Italy + '81' => 'JPN', # Japan + '52' => 'MEX', # Mexico + '31' => 'NLD', # Netherlands + '47' => 'NOR', # Norway + '64' => 'NZL', # New Zealand + '34' => 'ESP', # Spain + '46' => 'SWE', # Sweden + '41' => 'SWI', # Switzerland + } + + if @phone.phoneable + if @phone.phoneable_type == 'Tenant' + tenant = @phone.phoneable + language = tenant.language.code + elsif @phone.phoneable_type == 'User' + tenant = @phone.phoneable.current_tenant + language = @phone.phoneable.language.code + end + end + + if tenant && tenant.country + tone_scheme = tenant.country.country_code + end + + @phone_settings[:tone_scheme] = tone_schemes_map.include?(tone_scheme.to_s) ? tone_schemes_map[tone_scheme.to_s] : 'USA' + @phone_settings[:language] = languages_map.include?(language.to_s) ? languages_map[language.to_s] : 'English' + + xml_applications_url = "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{(@sip_accounts.blank? ? '0' : @sip_accounts.first[:id])}" + @dkeys = { + :menu => 'keyevent F_SETTINGS', + :retrieve => 'speed f-vmcheck', + :conf => 'keyevent F_CONFERENCE', + :redial => "url #{xml_applications_url}/call_history.xml?type=dialed", + :directory => "url #{xml_applications_url}/phone_book.xml", + :idle_ok => "url #{xml_applications_url}/call_history.xml?type=dialed", + :idle_cancel => "keyevent F_CANCEL", + :idle_up => "keyevent F_PREV_ID", + :idle_down => "keyevent F_NEXT_ID", + :idle_left => "url #{xml_applications_url}/call_history.xml?type=received", + :idle_right => "url #{xml_applications_url}/call_history.xml?type=missed", + } + + # Remap conference key to first conference if found + #conference = Conference.where(:conferenceable_type => @phone.phoneable_type, :conferenceable_id => @phone.phoneable_id).first + #if conference and conference.phone_numbers + # @dkeys[:conf] = "speed f_ta_#{conference.phone_numbers.first.number}" + #end + + @sip_accounts.length().upto(MAX_SIP_ACCOUNTS_COUNT) do |index| + snom_sip_account = { + :id => index, + :active => 'off', + :pname => '', + :pass => '', + :host => '', + :outbound => '', + :name => '', + :realname => '', + :idle_text => '', + } + @sip_accounts.push(snom_sip_account) + end + + @softkeys.length().upto(MAX_SOFTKEYS_COUNT) do |index| + @softkeys.push({:label => "", :data => "none"}) + end + + @state_settings_url = "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/state_settings.xml" + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render + } + } + end + + def idle_screen + + snom_360_bg = 'Qk0+BAAAAAAAAD4AAAAoAAAAgAAAAEAAAAABAAEAAAAAAAAEAAATCwAAEwsAAAIAAAACAAAA//// +AAAAAAAAAAAAAAAAAAAAAbbZxzbbAAAAAAAAAAAAAAG222222wAAAAAAAAAAAAAB9ttttt8AAAAA +AAAAAAAAAbbbbbbbAAAAAAAAAAAAAAG222222wAAAAAAAAAAAAABttttttsAAAAAAAAAAAAAAOPx +xx+OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkkkkkkkkkkkkkkAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAACSSSSSSSSSSSSSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAA' + + @phone_xml_object = { + :image => { + :data => snom_360_bg, + :location_x => 0, + :location_y => 0, + :invert => 0 + }, + :clock => { + :location_x => 128, + :location_y => 0, + }, + :date => { + :location_x => 100, + :location_y => 40, + }, + :line => { + :location_x => 0, + :location_y => 0, + }, + } + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render + } + } + end + + def log_in + + base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" + exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" + + log_in_number = params[:log_in].to_s.gsub(/[^0-9]/,'') + pin = params[:pin].to_s.gsub(/[^0-9]/,'') + + if ! params[:user].blank? + user = User.where(:id => params[:user].to_i).first + phone_number = PhoneNumber.where(:number => log_in_number, :phone_numberable_type => 'SipAccount').first + if phone_number + sip_account = phone_number.phone_numberable + end + elsif ! params[:log_in].blank? + phone_number = PhoneNumber.where(:number => log_in_number, :phone_numberable_type => 'SipAccount').first + if phone_number && phone_number.phone_numberable && phone_number.phone_numberable.sip_accountable && phone_number.phone_numberable.sip_accountable_type == 'User' + user = phone_number.phone_numberable.sip_accountable + end + end + + @phone_xml_object = { + :name => "snom_phone_text", + :title => "Error", + :prompt => "Log in", + :text => 'Log in failed!', + :fetch_url => base_url, + :fetch_mil => '2000', + } + + if ! user + @phone_xml_object = { + :name => "snom_phone_input", + :title => "Log In", + :prompt => "Log In", + :url => base_url, + :display_name => "Log In", + :query_string_param => "log_in", + :default_value => log_in_number, + :input_flags => "n", + :softkeys => [ + {:name => "F1", :label => "Exit", :url => exit_url} + ] + } + elsif pin.blank? + @phone_xml_object = { + :name => "snom_phone_input", + :title => "PIN", + :prompt => "PIN", + :url => base_url, + :display_name => "PIN", + :query_string_param => "user=#{user.id}&log_in=#{log_in_number}&pin", + :default_value => "", + :input_flags => "pn", + :softkeys => [ + {:name => "F1", :label => "Exit", :url => exit_url} + ] + } + elsif user.authenticate_by_pin?(pin) + if @phone.user_login(user, sip_account) + @phone_xml_object = { + :name => "snom_phone_text", + :title => "Log in successful", + :prompt => "Log in", + :text => "#{user.to_s} logged in", + :fetch_url => exit_url, + :fetch_mil => '1000', + } + end + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + end + + def log_out + if ! @phone + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Phone not found -->", + ) + return + end + + exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" + + if @phone.user_logout() + @phone_xml_object = { + :name => "snom_phone_text", + :title => "Log out successful", + :prompt => "Log out", + :text => 'Log out successful', + :fetch_url => exit_url, + :fetch_mil => '1000', + } + else + @phone_xml_object = { + :name => "snom_phone_text", + :title => "Error", + :prompt => "Log out", + :text => 'Log out failed!', + :fetch_url => exit_url, + :fetch_mil => '2000', + } + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + end + + def phone_book + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + @phone_xml_object = { + :name => 'snom_phone_directory', + :title => "$(lang:menu100_phone_book) #{@dialpad_keys}".strip, + :entries => [], + :softkeys => [], + } + + phone_books = Array.new() + phone_books = phone_books + @sip_account.sip_accountable.try(:phone_books).all + if @sip_account.sip_accountable.class == User + phone_books = phone_books + @sip_account.sip_accountable.try(:current_tenant).try(:phone_books).all + end + + phone_book_ids = Array.new() + phone_books.each do |phone_book| + phone_book_ids << phone_book.id + end + + PhoneBookEntry.where(:phone_book_id => phone_book_ids).order(:last_name).order(:first_name).limit(MAX_DIRECTORY_ENTRIES).each do |phone_book_entry| + if phone_book_entry.phone_numbers.count > 1 + @phone_xml_object[:entries] << { :text => phone_book_entry.to_s, :number => phone_book_entry.phone_numbers.first } + end + phone_book_entry.phone_numbers.each do |phone_number| + if phone_book_entry.phone_numbers.count > 1 + entry_name = " #{phone_number.name} #{phone_number.number}" + else + entry_name = "#{phone_book_entry.to_s} #{phone_number.number}" + end + + @phone_xml_object[:entries] << { :text => entry_name, :number => phone_number.number } + end + end + + base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" + phone_book_url = "#{base_url}?type=#{@type.to_s}" + for key_id in (0..9) + @phone_xml_object[:softkeys] << {:name => key_id, :url => "#{phone_book_url}&keys=#{@dialpad_keys.to_s}#{key_id}" } + end + @phone_xml_object[:softkeys] << {:name => '*', :url => "#{phone_book_url}&keys=#{@dialpad_keys.to_s[0..-2]}" } + @phone_xml_object[:softkeys] << {:name => '#', :url => "#{phone_book_url}&keys=" } + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + + end + + def call_history + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + if ['dialed', 'missed', 'received'].include? @type + @phone_xml_object = { + :name => "snom_phone_directory", + :title => "$(lang:menu100_call_lists) - #{@type.to_s.camelize}", + :entries => [] + } + + if @type == 'missed' + hunt_group_member_ids = PhoneNumber.where(:phone_numberable_type => 'HuntGroupMember', :number => @sip_account.phone_numbers.map {|a| a.number}).map {|a| a.phone_numberable_id} + hunt_group_ids = HuntGroupMember.where(:id => hunt_group_member_ids, :active => true).map {|a| a.hunt_group_id} + calls = CallHistory.where('entry_type = ? AND ((call_historyable_type = "SipAccount" AND call_historyable_id = ?) OR (call_historyable_type = "HuntGroup" AND call_historyable_id IN (?)))', @type, @sip_account.id, hunt_group_ids).order('start_stamp DESC').limit(MAX_DIRECTORY_ENTRIES) + else + calls = @sip_account.call_histories.where(:entry_type => @type).order('start_stamp DESC').limit(MAX_DIRECTORY_ENTRIES) + end + + calls.each do |call| + display_name = call.display_name + phone_number = call.display_number + phone_book_entry = call.phone_book_entry_by_number(phone_number) + if display_name.blank? + display_name = phone_book_entry.to_s + end + + @phone_xml_object[:entries].push({ + :selected => false, + :number => phone_number, + :text => "#{call_date_compact(call.start_stamp)} #{display_name} #{call.display_number}", + }) + end + else + base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" + @phone_xml_object = { + :name => 'snom_phone_menu', + :title => '$(lang:menu100_call_lists)', + :entries => [ + {:text => '$(lang:list_missed)', :url => "#{base_url}?&type=missed", :selected => false}, + {:text => '$(lang:list_taken)', :url => "#{base_url}?&type=received", :selected => false}, + {:text => '$(lang:list_dialed)', :url => "#{base_url}?&type=dialed", :selected => false}, + ] + } + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + + end + + def state_settings + @base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}" + + @sip_account_ids = Array.new() + @phone.sip_accounts.each do |sip_account| + if (sip_account.sip_accountable_type == @phone.phoneable_type) and (sip_account.sip_accountable_id == @phone.phoneable_id) + @sip_account_ids.push(sip_account.id) + end + end + + if @phone.hot_deskable + @enable_login = true + if @phone.phoneable_type != 'Tenant' + @enable_logout = true + end + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render + } + } + end + + def call_forwarding + if ! params[:type].blank? + @type = params[:type] + end + + if ! params[:function].blank? + @function = params[:function] + end + + if ! params[:id].blank? + @call_forwarding_id = params[:id].to_i + end + + if ! params[:sip_account].blank? + @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first + end + + if ! params[:account].blank? + @sip_account = SipAccount.where({ :id => params[:account].to_i }).first + end + + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" + + if @function == 'toggle' + if @call_forwarding_id + call_forwarding = @sip_account.call_forwards.where(:id => @call_forwarding_id).first + + if !call_forwarding and @sip_account.softkeys.where(:call_forward_id => @call_forwarding_id).count > 0 + call_forwarding = CallForward.where(:id => @call_forwarding_id).first + end + + if call_forwarding + call_forwarding.toggle + end + elsif @type + call_forwarding = @sip_account.call_forwarding_toggle(@type) + end + if !call_forwarding + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Call forwarding not set: #{@sip_account.errors.messages.inspect} -->", + ) + return + end + + if !call_forwarding.errors.blank? + error_messages = Array.new() + call_forwarding.errors.messages.each_pair do |key, message| + error_messages.push(message.join(';')) + end + @phone_xml_object = { + :name => 'snom_phone_text', + :title => t("call_forwards.name"), + :prompt => t("call_forwards.name"), + :text => "ERROR #{error_messages.join(',')} #{call_forwarding.to_s})", + :fetch_url => exit_url, + :fetch_mil => '1000', + } + elsif call_forwarding.active + @phone_xml_object = { + :name => 'snom_phone_text', + :title => t("call_forwards.name"), + :prompt => t("call_forwards.name"), + :text => "ON #{call_forwarding.to_s})", + :fetch_url => exit_url, + :fetch_mil => '1000', + } + else + @phone_xml_object = { + :name => 'snom_phone_text', + :title => t("call_forwards.name"), + :prompt => t("call_forwards.name"), + :text => "OFF #{call_forwarding.to_s}", + :fetch_url => exit_url, + :fetch_mil => '1000', + } + end + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + end + + def hunt_group + if ! params[:function].blank? + @function = params[:function] + end + + if ! params[:sip_account].blank? + @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first + end + + if ! params[:group].blank? + @hunt_group = HuntGroup.where({ :id => params[:group].to_i }).first + end + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + if ! @hunt_group + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- HuntGroup not found -->", + ) + return + end + + if ! params[:account].blank? + hunt_group_member = @hunt_group.hunt_group_members.where({ :id => params[:account].to_i }).first + end + + if ! hunt_group_member + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- HuntGroupMember not found -->", + ) + return + end + + exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" + + if @function == 'toggle' + if hunt_group_member.can_switch_status_itself == true + if hunt_group_member.active + hunt_group_member.active = false + else + hunt_group_member.active = true + end + + if ! hunt_group_member.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{hunt_group_member.errors.inspect} -->", + ) + return + end + end + + if hunt_group_member.active + @phone_xml_object = { + :name => 'snom_phone_text', + :title => 'Hunt Group', + :prompt => 'Hunt Group', + :text => "#{@hunt_group.name} on", + :fetch_url => exit_url, + :fetch_mil => '1000', + } + else + @phone_xml_object = { + :name => 'snom_phone_text', + :title => 'Hunt Group', + :prompt => 'Hunt Group', + :text => "#{@hunt_group.name} off", + :fetch_url => exit_url, + :fetch_mil => '1000', + } + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + end + end + + def acd + if ! params[:function].blank? + @function = params[:function] + end + + if ! params[:sip_account].blank? + @sip_account = SipAccount.where({ :id => params[:sip_account].to_i }).first + end + + if ! params[:acd].blank? + @acd = AutomaticCallDistributor.where({ :id => params[:acd].to_i }).first + end + + if ! @sip_account + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- SipAccount not found -->", + ) + return + end + + if ! @acd + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- AutomaticCallDistributor not found -->", + ) + return + end + + if ! params[:agent].blank? + acd_agent = @acd.acd_agents.where({ :id => params[:agent].to_i }).first + end + + if ! acd_agent + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- ACD Agent not found -->", + ) + return + end + + exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" + + if @function == 'toggle' + if acd_agent.status == 'active' + acd_agent.status = 'inactive' + else + acd_agent.status = 'active' + end + + if ! acd_agent.save + render( + :status => 500, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- #{acd_agent.errors.inspect} -->", + ) + return + end + + if acd_agent.status == 'active' + @phone_xml_object = { + :name => 'snom_phone_text', + :title => 'ACD', + :prompt => 'ACD', + :text => "#{@acd.name} on", + :fetch_url => exit_url, + :fetch_mil => '1000', + } + else + @phone_xml_object = { + :name => 'snom_phone_text', + :title => 'ACD', + :prompt => 'ACD', + :text => "#{@acd.name} off", + :fetch_url => exit_url, + :fetch_mil => '1000', + } + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :action => "_#{@phone_xml_object[:name]}" + } + } + end + end + + def exit + render( + :status => 200, + :layout => false, + :content_type => 'text/xml', + :text => "<exit />", + ) + end + + def call_date_compact(date) + if date.strftime('%Y%m%d') == DateTime::now.strftime('%Y%m%d') + return date.strftime('%H:%M') + end + return date.strftime('%d.%m %H:%M') + end + +end diff --git a/app/controllers/fax_accounts_controller.rb b/app/controllers/fax_accounts_controller.rb new file mode 100644 index 0000000..ce03bc5 --- /dev/null +++ b/app/controllers/fax_accounts_controller.rb @@ -0,0 +1,82 @@ +class FaxAccountsController < ApplicationController + load_resource :user + load_resource :user_group + load_and_authorize_resource :fax_account, :through => [:user, :user_group] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @fax_account = @parent.fax_accounts.build + @fax_account.name = generate_a_new_name(@parent, @fax_account) + @fax_account.days_till_auto_delete = DAYS_TILL_AUTO_DELETE + @fax_account.retries = DEFAULT_NUMBER_OF_RETRIES + @fax_account.station_id = @parent.to_s + @fax_account.phone_numbers.build + if @parent.class == User && !@parent.email.blank? + @fax_account.email = @parent.email + end + end + + def create + @fax_account = @parent.fax_accounts.build(params[:fax_account]) + if @fax_account.save + m = method( :"#{@parent.class.name.underscore}_fax_account_path" ) + redirect_to m.( @parent, @fax_account ), :notice => t('fax_accounts.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @fax_account.update_attributes(params[:fax_account]) + m = method( :"#{@parent.class.name.underscore}_fax_account_path" ) + redirect_to m.( @parent, @fax_account ), :notice => t('fax_accounts.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @fax_account.destroy + m = method( :"#{@parent.class.name.underscore}_fax_accounts_url" ) + redirect_to m.( @parent ), :notice => t('fax_accounts.controller.successfuly_destroyed') + end + + private + def set_and_authorize_parent + @parent = @user || @user_group + authorize! :read, @parent + end + + def spread_breadcrumbs + if @parent && @parent.class == User + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t("fax_accounts.index.page_title"), user_fax_accounts_path(@user) + if @fax_account && !@fax_account.new_record? + add_breadcrumb @fax_account, user_fax_account_path(@user, @fax_account) + end + end + + if @parent && @parent.class == UserGroup + @user_group = @parent + add_breadcrumb t("user_groups.index.page_title"), tenant_user_groups_path(@user_group.tenant) + add_breadcrumb @user_group, tenant_user_group_path(@user_group.tenant, @user_group) + add_breadcrumb t("fax_accounts.index.page_title"), user_group_fax_accounts_path(@user_group) + if @fax_account && !@fax_account.new_record? + add_breadcrumb @fax_account, user_group_fax_account_path(@user_group, @fax_account) + end + end + end + +end diff --git a/app/controllers/fax_documents_controller.rb b/app/controllers/fax_documents_controller.rb new file mode 100644 index 0000000..eff9604 --- /dev/null +++ b/app/controllers/fax_documents_controller.rb @@ -0,0 +1,82 @@ +class FaxDocumentsController < ApplicationController + load_and_authorize_resource :fax_account + load_and_authorize_resource :fax_document, :through => [:fax_account] + + before_filter :spread_breadcrumbs + + def index + @fax_documents = @fax_documents.order(:created_at).reverse_order + end + + def show + respond_to do |format| + @fax_document = FaxDocument.find(params[:id]) + format.html + format.xml { render :xml => @fax_document } + format.pdf { + caller_number = @fax_document.caller_id_number.to_s.gsub(/[^0-9]/, '') + if caller_number.blank? + caller_number = 'anonymous' + end + + if @fax_document.document.path + send_file @fax_document.document.path, :type => "application/pdf", + :filename => "#{@fax_document.created_at.strftime('%Y%m%d-%H%M%S')}-#{caller_number}.pdf" + else + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Document not found -->", + ) + end + } + end + end + + def new + @fax_document = @fax_account.fax_documents.build + @phone_number = @fax_document.build_destination_phone_number + end + + def create + @fax_document = @fax_account.fax_documents.build(params[:fax_document]) + @fax_document.retry_counter = @fax_account.retries + if @fax_document.save + @fax_document.queue_for_sending! + redirect_to fax_account_fax_document_path(@fax_document.fax_account, @fax_document), :notice => t('fax_documents.controller.successfuly_created') + else + render :new + end + end + + def destroy + @fax_account = FaxAccount.find(params[:fax_account_id]) + @fax_document = @fax_account.fax_documents.find(params[:id]) + @fax_document.destroy + redirect_to fax_account_fax_documents_url, :notice => t('fax_documents.controller.successfuly_destroyed') + end + + private + def spread_breadcrumbs + breadcrumbs = [] + breadcrumbs = case @fax_account.fax_accountable.class.to_s + when 'User' ; [ + [@fax_account.fax_accountable.to_s, user_path(@fax_account.fax_accountable)], + [t('fax_accounts.name').pluralize, user_fax_accounts_path(@fax_account.fax_accountable)], + [t('fax_documents.name').pluralize, fax_account_fax_documents_path(@fax_account)], + ] + when 'UserGroup' ; [ + [@fax_account.fax_accountable, user_group_path(@fax_account.fax_accountable)], + [t('fax_accounts.name').pluralize, user_group_fax_accounts_path(@fax_account.fax_accountable)], + [t('fax_documents.name').pluralize, fax_account_fax_documents_path(@fax_account)], + ] + end + if !breadcrumbs.blank? + breadcrumbs.each do |breadcrumb| + add_breadcrumb breadcrumb[0], breadcrumb[1] + end + end + end + +end diff --git a/app/controllers/freeswitch_voicemail_msgs_controller.rb b/app/controllers/freeswitch_voicemail_msgs_controller.rb new file mode 100644 index 0000000..085db3d --- /dev/null +++ b/app/controllers/freeswitch_voicemail_msgs_controller.rb @@ -0,0 +1,7 @@ +class FreeswitchVoicemailMsgsController < ApplicationController + load_and_authorize_resource :sip_account + load_and_authorize_resource :freeswitch_voicemail_msg, :through => [:sip_account] + + def index + end +end diff --git a/app/controllers/gemeinschaft_setups_controller.rb b/app/controllers/gemeinschaft_setups_controller.rb new file mode 100644 index 0000000..cafb8a3 --- /dev/null +++ b/app/controllers/gemeinschaft_setups_controller.rb @@ -0,0 +1,61 @@ +class GemeinschaftSetupsController < ApplicationController + load_and_authorize_resource :gemeinschaft_setup + + skip_before_filter :go_to_setup_if_new_installation + # before_filter :redirect_if_not_a_fresh_installation + + def new + @user = @gemeinschaft_setup.build_user( + :user_name => t('gemeinschaft_setups.initial_setup.admin_name'), + :male => true, + :email => 'admin@localhost', + ) + @sip_domain = @gemeinschaft_setup.build_sip_domain( + :host => guess_local_host(), + :realm => guess_local_host(), + ) + @gemeinschaft_setup.country = Country.find_by_name('Germany') + @gemeinschaft_setup.language = Language.find_by_name('Deutsch') + end + + def create + if @gemeinschaft_setup.save + super_tenant = Tenant.create( + :name => SUPER_TENANT_NAME, + :country_id => @gemeinschaft_setup.country.id, + :language_id => @gemeinschaft_setup.language_id, + :description => t('gemeinschaft_setups.initial_setup.super_tenant_description'), + ) + + # Admin + user = @gemeinschaft_setup.user + super_tenant.tenant_memberships.create(:user_id => user.id) + user.update_attributes(:current_tenant_id => super_tenant.id) + + # Create the Super-Tenant's group: + super_tenant_super_admin_group = super_tenant.user_groups.create(:name => t('gemeinschaft_setups.initial_setup.super_admin_group_name')) + super_tenant_super_admin_group.user_group_memberships.create(:user_id => user.id) + + # Auto-Login: + session[:user_id] = user.id + + # Redirect to the user + redirect_to new_tenant_url, :notice => t('gemeinschaft_setups.initial_setup.successful_setup') + else + render :new + end + end + + private + + def redirect_if_not_a_fresh_installation + if GemeinschaftSetup.all.count > 0 + if current_user + redirect_to root_url , :alert => t('gemeinschaft_setups.initial_setup.access_denied_only_available_on_a_new_system') + else + redirect_to log_in_path , :alert => t('gemeinschaft_setups.initial_setup.access_denied_only_available_on_a_new_system') + end + end + end + +end diff --git a/app/controllers/gs_cluster_sync_log_entries_controller.rb b/app/controllers/gs_cluster_sync_log_entries_controller.rb new file mode 100644 index 0000000..3e65037 --- /dev/null +++ b/app/controllers/gs_cluster_sync_log_entries_controller.rb @@ -0,0 +1,25 @@ +class GsClusterSyncLogEntriesController < ApplicationController + + # GET /gs_cluster_sync_log_entries/new.json + def new + @gs_cluster_sync_log_entry = GsClusterSyncLogEntry.new + + respond_to do |format| + format.json { render json: @gs_cluster_sync_log_entry } + end + end + + # POST /gs_cluster_sync_log_entries.json + def create + @gs_cluster_sync_log_entry = GsClusterSyncLogEntry.new(params[:gs_cluster_sync_log_entry]) + + respond_to do |format| + if @gs_cluster_sync_log_entry.save + format.json { render json: @gs_cluster_sync_log_entry, status: :created, location: @gs_cluster_sync_log_entry } + else + format.json { render json: @gs_cluster_sync_log_entry.errors, status: :unprocessable_entity } + end + end + end + +end diff --git a/app/controllers/gs_nodes_controller.rb b/app/controllers/gs_nodes_controller.rb new file mode 100644 index 0000000..3667775 --- /dev/null +++ b/app/controllers/gs_nodes_controller.rb @@ -0,0 +1,170 @@ +class GsNodesController < ApplicationController + + load_and_authorize_resource :gs_node, :only => [:index, :show, :new, :create, :edit, :update, :destroy] + + before_filter :spread_breadcrumbs + + def index + + end + + def show + + end + + def new + @gs_node = GsNode.new + @gs_node.push_updates_to = true + @gs_node.accepts_updates_from = true + @gs_node.element_name = 'gs_cluster_sync_log_entry' + end + + def create + @gs_node = GsNode.new(params[:gs_node]) + if @gs_node.save + redirect_to @gs_node, :notice => t('gs_nodes.controller.successfuly_created') + else + render :new + end + end + + def edit + @gs_node = GsNode.find(params[:id]) + end + + def update + @gs_node = GsNode.find(params[:id]) + if @gs_node.update_attributes(params[:gs_node]) + redirect_to @gs_node, :notice => t('gs_nodes.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @gs_node = GsNode.find(params[:id]) + @gs_node.destroy + redirect_to gs_nodes_url, :notice => t('gs_nodes.controller.successfuly_destroyed') + end + + def sync + if !GsNode.where(:ip_address => request.remote_ip).first + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Node not found -->", + ) + return + end + + if ! params[:newer].blank? + @newer_as = Time.at(params[:newer].to_i) + else + @newer_as = Time.at(0) + end + + if ! params[:class].blank? + @request_class = params[:class].to_s + else + @request_class = ''; + end + + @node = GsNode.where(:ip_address => HOMEBASE_IP_ADDRESS).first + + if @request_class.blank? || @request_class == "tenants" + @tenants = Tenant.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "user_groups" + @user_groups = UserGroup.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "users" + @users = User.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "user_group_memberships" + @user_group_memberships = UserGroupMembership.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "sip_accounts" + @sip_accounts = SipAccount.where('updated_at > ?',@newer_as) + end + + if @request_class.blank? || @request_class == "conferences" + @conferences = Conference.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "fax_accounts" + @fax_accounts = FaxAccount.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "phone_books" + @phone_books = PhoneBook.where('updated_at > ?',@newer_as) + end + + if @request_class.blank? || @request_class == "phone_book_entries" + @phone_book_entries = PhoneBookEntry.where('updated_at > ?',@newer_as) + end + + if @request_class.blank? || @request_class == "phone_numbers" + @phone_numbers = PhoneNumber.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "call_forwards" + @call_forwards = CallForward.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "softkeys" + @softkeys = Softkey.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "ringtones" + @ringtones = Ringtone.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "conference_invitees" + @conference_invitees = ConferenceInvitee.where('updated_at > ?', @newer_as) + end + + if @request_class == "fax_documents" + @fax_documents = FaxDocument.where('updated_at > ?', @newer_as) + end + + if @request_class == "call_histories" + @call_histories = CallHistory.where('updated_at > ?', @newer_as) + end + + if @request_class.blank? || @request_class == "deleted_items" + @deleted_items = Array.new + deleted_items_log = GsClusterSyncLogEntry.where('action = "destroy" AND updated_at > ?', @newer_as) + deleted_items_log.each do |deleted_item_log_entry| + content = JSON(deleted_item_log_entry.content) + content['class_name'] = deleted_item_log_entry.class_name + if content['uuid'] + @deleted_items << content + end + end + end + + if params[:image].to_s == 'false' + @image_include = false + else + @image_include = true + end + + end + + private + + def spread_breadcrumbs + if @gs_node + add_breadcrumb t("gs_nodes.index.page_title"), gs_nodes_path + + if @gs_node && !@gs_node.new_record? + add_breadcrumb @gs_node, gs_node_path(@gs_node) + end + end + end +end diff --git a/app/controllers/gui_functions_controller.rb b/app/controllers/gui_functions_controller.rb new file mode 100644 index 0000000..2ab2c5e --- /dev/null +++ b/app/controllers/gui_functions_controller.rb @@ -0,0 +1,73 @@ +class GuiFunctionsController < ApplicationController + before_filter :load_user_groups + before_filter :spread_breadcrumbs + + def index + @gui_functions = GuiFunction.order(:category, :name) + end + + def show + @gui_function = GuiFunction.find(params[:id]) + end + + def new + @gui_function = GuiFunction.new + + @user_groups.each do |user_group| + if @gui_function.user_groups.where(:id => user_group.id).count == 0 + @gui_function.gui_function_memberships.build(:user_group_id => user_group.id, :activated => true) + end + end + end + + def create + @gui_function = GuiFunction.new(params[:gui_function]) + + if @gui_function.save + redirect_to @gui_function, :notice => t('gui_functions.controller.successfuly_created') + else + render :new + end + end + + def edit + @gui_function = GuiFunction.find(params[:id]) + @user_groups.each do |user_group| + if @gui_function.user_groups.where(:id => user_group.id).count == 0 + @gui_function.gui_function_memberships.build(:user_group_id => user_group.id, :activated => true) + end + end + end + + def update + @gui_function = GuiFunction.find(params[:id]) + if @gui_function.update_attributes(params[:gui_function]) + redirect_to @gui_function, :notice => t('gui_functions.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @gui_function = GuiFunction.find(params[:id]) + @gui_function.destroy + redirect_to gui_functions_url, :notice => t('gui_functions.controller.successfuly_destroyed') + end + + private + def load_user_groups + @user_groups = Tenant.find(@current_user.current_tenant).user_groups.order(:position) + end + + def spread_breadcrumbs + if @tenant + add_breadcrumb t("user_groups.index.page_title"), tenant_user_groups_path(@tenant) + if @user_group && !@user_group.new_record? + add_breadcrumb @user_group, tenant_user_group_path(@tenant, @user_group) + end + end + + add_breadcrumb t("gui_functions.index.page_title"), gui_functions_path + end + +end diff --git a/app/controllers/hunt_group_members_controller.rb b/app/controllers/hunt_group_members_controller.rb new file mode 100644 index 0000000..90206ee --- /dev/null +++ b/app/controllers/hunt_group_members_controller.rb @@ -0,0 +1,67 @@ +class HuntGroupMembersController < ApplicationController + load_and_authorize_resource :hunt_group + load_and_authorize_resource :hunt_group_member, :through => [:hunt_group] + + before_filter :spread_breadcrumbs + + def index + if params[:active] + if params[:active].downcase == 'true' + @hunt_group_members = @hunt_group_members.where(:active => true) + elsif params[:active].downcase == 'false' + @hunt_group_members = @hunt_group_members.where(:active => false) + end + end + end + + def show + end + + def new + @hunt_group_member = @hunt_group.hunt_group_members.build + + i = @hunt_group.hunt_group_members.count + loop do + i += 1 + break unless @hunt_group.hunt_group_members.where(:name => "#{t('hunt_group_members.name')} #{i}").count > 0 + end + @hunt_group_member.name = "#{t('hunt_group_members.name')} #{i}" + @hunt_group_member.active = true + @hunt_group_member.can_switch_status_itself = true + end + + def create + @hunt_group_member = @hunt_group.hunt_group_members.build(params[:hunt_group_member]) + if @hunt_group_member.save + redirect_to hunt_group_hunt_group_member_path(@hunt_group, @hunt_group_member), :notice => t('hunt_group_members.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @hunt_group_member.update_attributes(params[:hunt_group_member]) + redirect_to hunt_group_hunt_group_member_path(@hunt_group, @hunt_group_member), :notice => t('hunt_group_members.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @hunt_group_member.destroy + redirect_to hunt_group_hunt_group_members_path(@hunt_group), :notice => t('hunt_group_members.controller.successfuly_destroyed') + end + + def spread_breadcrumbs + add_breadcrumb t("hunt_groups.index.page_title"), tenant_hunt_groups_path(@hunt_group.tenant) + add_breadcrumb @hunt_group, tenant_hunt_group_path(@hunt_group.tenant, @hunt_group) + add_breadcrumb t("hunt_group_members.index.page_title"), hunt_group_hunt_group_members_path(@hunt_group) + if @hunt_group_member && !@hunt_group_member.new_record? + add_breadcrumb @hunt_group_member, hunt_group_hunt_group_member_path(@hunt_group, @hunt_group_member) + end + end + +end diff --git a/app/controllers/hunt_groups_controller.rb b/app/controllers/hunt_groups_controller.rb new file mode 100644 index 0000000..13a556a --- /dev/null +++ b/app/controllers/hunt_groups_controller.rb @@ -0,0 +1,55 @@ +class HuntGroupsController < ApplicationController + load_and_authorize_resource :tenant + load_and_authorize_resource :hunt_group, :through => [:tenant] + + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + i = @tenant.hunt_groups.count + loop do + i += 1 + break unless @tenant.hunt_groups.where(:name => "#{t('hunt_groups.name')} #{i}").count > 0 + end + @hunt_group = @tenant.hunt_groups.build(:name => "#{t('hunt_groups.name')} #{i}") + end + + def create + @hunt_group = @tenant.hunt_groups.build(params[:hunt_group]) + if @hunt_group.save + redirect_to tenant_hunt_group_path(@tenant, @hunt_group), :notice => t('hunt_groups.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + @hunt_group = HuntGroup.find(params[:id]) + if @hunt_group.update_attributes(params[:hunt_group]) + redirect_to tenant_hunt_group_path(@tenant, @hunt_group), :notice => t('hunt_groups.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @hunt_group.destroy + redirect_to tenant_hunt_groups_path(@tenant), :notice => t('hunt_groups.controller.successfuly_destroyed') + end + + private + def spread_breadcrumbs + add_breadcrumb t("hunt_groups.index.page_title"), tenant_hunt_groups_path(@tenant) + if @hunt_group && !@hunt_group.new_record? + add_breadcrumb @hunt_group, tenant_hunt_group_path(@tenant, @hunt_group) + end + end +end diff --git a/app/controllers/manufacturers_controller.rb b/app/controllers/manufacturers_controller.rb new file mode 100644 index 0000000..1bcf9de --- /dev/null +++ b/app/controllers/manufacturers_controller.rb @@ -0,0 +1,49 @@ +class ManufacturersController < ApplicationController + load_and_authorize_resource :manufacturer + + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + end + + def create + @manufacturer = Manufacturer.new(params[:manufacturer]) + if @manufacturer.save + redirect_to @manufacturer, :notice => t('manufacturers.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @manufacturer.update_attributes(params[:manufacturer]) + redirect_to @manufacturer, :notice => t('manufacturers.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @manufacturer.destroy + redirect_to manufacturers_url, :notice => t('manufacturers.controller.successfuly_destroyed') + end + + private + + def spread_breadcrumbs + add_breadcrumb t("manufacturers.index.page_title"), manufacturers_path + if @manufacturer && !@manufacturer.new_record? + add_breadcrumb @manufacturer, manufacturer_path(@manufacturer) + end + end + +end diff --git a/app/controllers/page_controller.rb b/app/controllers/page_controller.rb new file mode 100644 index 0000000..1f37449 --- /dev/null +++ b/app/controllers/page_controller.rb @@ -0,0 +1,24 @@ +class PageController < ApplicationController + # load_and_authorize_resource :class => false + # CanCan doesn't work here really good because Page is not a resource. + + before_filter :if_fresh_system_then_go_to_wizard + skip_before_filter :home_breadcrumb, :only => [:index] + + def index;end + def conference;end + + private + def if_fresh_system_then_go_to_wizard + if Tenant.count == 0 && User.count == 0 + # This is a brand new system. We need to run a setup first. + redirect_to wizards_new_initial_setup_path + else + if current_user.nil? + # You need to login first. + redirect_to log_in_path, :alert => I18n.t('pages.controller.access_denied_login_first') + end + end + end + +end diff --git a/app/controllers/phone_book_entries_controller.rb b/app/controllers/phone_book_entries_controller.rb new file mode 100644 index 0000000..823d50e --- /dev/null +++ b/app/controllers/phone_book_entries_controller.rb @@ -0,0 +1,135 @@ +class PhoneBookEntriesController < ApplicationController + load_and_authorize_resource :phone_book + load_and_authorize_resource :phone_book_entry, :through => :phone_book, :shallow => true + + before_filter :spread_breadcrumbs + + def index + # In case this is a search params[:q] or params[:name] will contain the query. + # + @query = params[:q] + @query ||= params[:name] + @query = @query.strip if @query + + if !@query.blank? + if @query.match(/^\+?\d+$/) != nil + # Find by phone number + phone_book_entries_ids = @phone_book_entries.map{|entry| entry.id} + @found_phone_numbers = PhoneNumber. + where(:phone_numberable_type => 'PhoneBookEntry', :phone_numberable_id => phone_book_entries_ids). + where('number LIKE ?', "#{@query}%") + @search_result = @phone_book_entries.where(:id => @found_phone_numbers.map{|entry| entry.phone_numberable_id}) + elsif @query.match(/^[\"\'](.*)[\"\']$/) != nil + # The User searched for =>'example'<= so he wants an EXACT search for that. + # This is the fasted and most accurate way of searching. + # The order to search is: last_name, first_name and organization. + # It stops searching as soon as it finds results. + # + @query = $1 + @search_result = @phone_book_entries.where(:last_name => @query) + @search_result = @phone_book_entries.where(:first_name => @query) if @search_result.count == 0 + @search_result = @phone_book_entries.where(:organization => @query) if @search_result.count == 0 + + @exact_search = true + else + # Search with SQL LIKE + # + @search_result = @phone_book_entries. + where( '( ( last_name LIKE ? ) OR ( first_name LIKE ? ) OR ( organization LIKE ? ) )', + "#{@query}%", "#{@query}%", "#{@query}%" ) + + @exact_search = false + end + + # Let's have a run with our phonetic search. + # + phonetic_query = PhoneBookEntry.koelner_phonetik(@query) + @phonetic_search_result = @phone_book_entries.where(:last_name_phonetic => phonetic_query) + @phonetic_search_result = @phone_book_entries.where(:first_name_phonetic => phonetic_query) if @phonetic_search_result.count == 0 + @phonetic_search_result = @phone_book_entries.where(:organization_phonetic => phonetic_query) if @phonetic_search_result.count == 0 + + if @phonetic_search_result.count == 0 + # Let's try the search with SQL LIKE. Just in case. + # + @phonetic_search_result = @phone_book_entries.where( 'last_name_phonetic LIKE ?', "#{phonetic_query}%" ) + @phonetic_search_result = @phone_book_entries.where( 'first_name_phonetic LIKE ?', "#{phonetic_query}%" ) if @phonetic_search_result.count == 0 + @phonetic_search_result = @phone_book_entries.where( 'organization_phonetic LIKE ?', "#{phonetic_query}%" ) if @phonetic_search_result.count == 0 + end + + @phonetic_search = true if @phonetic_search_result.count > 0 + + @phone_book_entries = @search_result + + if @phone_book_entries.count == 0 && @exact_search == false && @phonetic_search + @phone_book_entries = @phonetic_search_result + end + end + + # Let's sort the results and do pagination. + # + @phone_book_entries = @phone_book_entries. + order([ :last_name, :first_name, :organization ]). + paginate( + :page => @pagination_page_number, + :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE + ) + end + + def show + end + + def new + @phone_book_entry = @phone_book.phone_book_entries.build + @phone_book_entry.is_male = true + end + + def create + @phone_book_entry = @phone_book.phone_book_entries.build( params[:phone_book_entry] ) + if @phone_book_entry.save + redirect_to phone_book_phone_book_entry_path( @phone_book, @phone_book_entry ), :notice => t('phone_book_entries.controller.successfuly_created', :resource => @phone_book_entry) + else + render :new + end + end + + def edit + end + + def update + if @phone_book_entry.update_attributes(params[:phone_book_entry]) + redirect_to @phone_book_entry, :notice => t('phone_book_entries.controller.successfuly_updated', :resource => @phone_book_entry) + else + render :edit + end + end + + def destroy + @phone_book_entry.destroy + redirect_to phone_book_entries_url, :notice => t('phone_book_entries.controller.successfuly_destroyed') + end + + private + + def spread_breadcrumbs + if @phone_book + if @phone_book.phone_bookable.class == Tenant + add_breadcrumb t("phone_books.index.page_title"), tenant_phone_books_path(@phone_book.phone_bookable) + add_breadcrumb @phone_book, tenant_phone_book_path(@phone_book.phone_bookable, @phone_book) + add_breadcrumb t("phone_book_entries.index.page_title"), phone_book_phone_book_entries_path(@phone_book) + end + + if @phone_book.phone_bookable.class == User + add_breadcrumb t("users.index.page_title"), tenant_users_path(@phone_book.phone_bookable.current_tenant) + add_breadcrumb @phone_book.phone_bookable, tenant_user_path(@phone_book.phone_bookable.current_tenant, @phone_book.phone_bookable) + add_breadcrumb t("phone_books.index.page_title"), user_phone_books_path(@phone_book.phone_bookable) + add_breadcrumb @phone_book, user_phone_book_path(@phone_book.phone_bookable, @phone_book) + add_breadcrumb t("phone_book_entries.index.page_title"), phone_book_phone_book_entries_path(@phone_book) + end + + if @phone_book_entry && !@phone_book_entry.new_record? + add_breadcrumb @phone_book_entry, phone_book_phone_book_entry_path(@phone_book, @phone_book_entry) + end + end + end + +end diff --git a/app/controllers/phone_books_controller.rb b/app/controllers/phone_books_controller.rb new file mode 100644 index 0000000..54e7889 --- /dev/null +++ b/app/controllers/phone_books_controller.rb @@ -0,0 +1,105 @@ +class PhoneBooksController < ApplicationController + load_resource :user + load_resource :user_group + load_resource :tenant + load_and_authorize_resource :phone_book, :through => [:user, :user_group, :tenant] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + @by_name = params[:name] + + @pagination_page_number = params[:page].to_i + @pagination_page_number = 1 if @pagination_page_number < 1 + + if @by_name.blank? + @phone_book_entries = @phone_book. + phone_book_entries. + order([ :last_name, :first_name ]). + paginate( + :page => @pagination_page_number, + :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE + ) + else + # search by name + @by_name = @by_name. + gsub( /[^A-Za-z0-9#]/, '' ). + gsub('*','?'). + gsub('%','_'). + gsub(/^#/,''). + upcase + + @phone_book_entries = @phone_book. + phone_book_entries. + where( '( ( last_name LIKE ? ) OR ( first_name LIKE ? ) )', "#{@by_name}%", "#{@by_name}%" ). + order([ :last_name, :first_name ]). + paginate( + :page => @pagination_page_number, + :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE + ) + end + end + + def new + @phone_book = @parent.phone_books.build + @phone_book.name = generate_a_new_name(@parent, @phone_book) + end + + def create + @phone_book = @parent.phone_books.build( params[:phone_book] ) + if @phone_book.save + m = method( :"#{@parent.class.name.underscore}_phone_book_path" ) + redirect_to m.( @parent, @phone_book ), :notice => t('phone_books.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @phone_book.update_attributes(params[:phone_book]) + m = method( :"#{@parent.class.name.underscore}_phone_book_path" ) + redirect_to m.( @parent, @phone_book ), :notice => t('phone_books.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @phone_book.destroy + m = method( :"#{@parent.class.name.underscore}_phone_books_url" ) + redirect_to m.( @parent ), :notice => t('phone_books.controller.successfuly_destroyed') + end + + private + def set_and_authorize_parent + @parent = @user || @user_group || @tenant + authorize! :read, @parent + end + + def spread_breadcrumbs + if @parent.class == Tenant + add_breadcrumb t("phone_books.index.page_title"), tenant_phone_books_path(@tenant) + if @phone_book && !@phone_book.new_record? + add_breadcrumb @phone_book, tenant_phone_book_path(@tenant, @phone_book) + end + end + + if @parent.class == User + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t("phone_books.index.page_title"), user_phone_books_path(@user) + if @phone_book && !@phone_book.new_record? + add_breadcrumb @phone_book, user_phone_book_path(@user, @phone_book) + end + end + + end + +end diff --git a/app/controllers/phone_models_controller.rb b/app/controllers/phone_models_controller.rb new file mode 100644 index 0000000..59facdf --- /dev/null +++ b/app/controllers/phone_models_controller.rb @@ -0,0 +1,52 @@ +class PhoneModelsController < ApplicationController + load_and_authorize_resource :manufacturer + load_and_authorize_resource :phone_model, :through => [:manufacturer] + + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @phone_model = @manufacturer.phone_models.build + end + + def create + @phone_model = @manufacturer.phone_models.build.new(params[:phone_model]) + if @phone_model.save + redirect_to manufacturer_phone_model_path( @manufacturer, @phone_model ), :notice => t('phone_models.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @phone_model.update_attributes(params[:phone_model]) + redirect_to manufacturer_phone_model_path( @manufacturer, @phone_model ), :notice => t('phone_models.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @phone_model.destroy + redirect_to manufacturer_phone_models_url( @manufacturer ), :notice => t('phone_models.controller.successfuly_destroyed') + end + + private + + def spread_breadcrumbs + add_breadcrumb t("manufacturers.index.page_title"), manufacturers_path + add_breadcrumb @manufacturer, manufacturer_path(@manufacturer) + add_breadcrumb t("phone_models.index.page_title"), manufacturer_phone_models_path(@manufacturer) + if @phone_model && !@phone_model.new_record? + add_breadcrumb @phone_model, manufacturer_phone_model_path(@manufacturer, @phone_model) + end + end +end diff --git a/app/controllers/phone_number_ranges_controller.rb b/app/controllers/phone_number_ranges_controller.rb new file mode 100644 index 0000000..a4e7238 --- /dev/null +++ b/app/controllers/phone_number_ranges_controller.rb @@ -0,0 +1,56 @@ +class PhoneNumberRangesController < ApplicationController + load_and_authorize_resource :tenant + load_and_authorize_resource :phone_number_range, :through => [:tenant] + + before_filter :set_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @phone_number_range = @parent.phone_number_ranges.build + end + + def create + @phone_number_range = @parent.phone_number_ranges.build(params[:phone_number_range]) + if @phone_number_range.save + redirect_to @phone_number_range, :notice => t('phone_number_ranges.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @phone_number_range.update_attributes(params[:phone_number_range]) + redirect_to @phone_number_range, :notice => t('phone_number_ranges.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @phone_number_range.destroy + redirect_to phone_number_ranges_url, :notice => t('phone_number_ranges.controller.successfuly_destroyed') + end + + private + + def set_parent + @parent = @tenant + end + + def spread_breadcrumbs + add_breadcrumb t("phone_number_ranges.index.page_title"), tenant_phone_number_ranges_path(@tenant) + if @phone_number_range && !@phone_number_range.new_record? + add_breadcrumb t("phone_number_ranges.ranges.#{@phone_number_range}.label"), tenant_phone_number_range_path(@tenant, @phone_number_range) + end + end + +end diff --git a/app/controllers/phone_numbers_controller.rb b/app/controllers/phone_numbers_controller.rb new file mode 100644 index 0000000..065934c --- /dev/null +++ b/app/controllers/phone_numbers_controller.rb @@ -0,0 +1,226 @@ +class PhoneNumbersController < ApplicationController + load_resource :phone_book_entry + load_resource :sip_account + load_resource :conference + load_resource :fax_account + load_resource :phone_number_range + load_resource :callthrough + load_resource :whitelist + load_resource :access_authorization + load_resource :hunt_group + load_resource :hunt_group_member + load_resource :automatic_call_distributor + load_and_authorize_resource :phone_number, :through => [:phone_book_entry, :sip_account, :conference, + :fax_account, :phone_number_range, :callthrough, + :whitelist, :access_authorization, :hunt_group, + :hunt_group_member, :automatic_call_distributor] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + @ringtoneable_classes = { + 'SipAccount' => true, + 'HuntGroup' => true, + 'AutomaticCallDistributor' => true, + 'PhoneBookEntry' => true, + } + @forwardable_classes = { + 'SipAccount' => true, + 'HuntGroup' => true, + 'AutomaticCallDistributor' => true, + } + end + + def new + @phone_number = @parent.phone_numbers.build() + end + + def create + @phone_number = @parent.phone_numbers.new( params[:phone_number] ) + if @phone_number.save + m = method( :"#{@parent.class.name.underscore}_phone_number_path" ) + redirect_to m.( @parent, @phone_number ), :notice => t('phone_numbers.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @phone_number.update_attributes(params[:phone_number]) + m = method( :"#{@parent.class.name.underscore}_phone_number_path" ) + redirect_to m.( @parent, @phone_number ), :notice => t('phone_numbers.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @phone_number.destroy + m = method( :"#{@parent.class.name.underscore}_phone_numbers_url" ) + redirect_to m.(), :notice => t('phone_numbers.controller.successfuly_destroyed') + end + + def move_higher + @phone_number.move_higher + redirect_to :back + end + + def move_lower + @phone_number.move_lower + redirect_to :back + end + + private + def set_and_authorize_parent + @parent = @phone_book_entry || @sip_account || @conference || @fax_account || + @phone_number_range || @callthrough || @whitelist || @access_authorization || + @hunt_group || @hunt_group_member || @automatic_call_distributor + + authorize! :read, @parent + + @show_path_method = method( :"#{@parent.class.name.underscore}_phone_number_path" ) + @index_path_method = method( :"#{@parent.class.name.underscore}_phone_numbers_path" ) + @new_path_method = method( :"new_#{@parent.class.name.underscore}_phone_number_path" ) + @edit_path_method = method( :"edit_#{@parent.class.name.underscore}_phone_number_path" ) + end + + def spread_breadcrumbs + if @parent.class == Callthrough + add_breadcrumb t("#{@parent.class.name.underscore.pluralize}.index.page_title"), tenant_callthroughs_path(@parent.tenant) + add_breadcrumb @callthrough, tenant_callthrough_path(@parent.tenant, @callthrough) + add_breadcrumb t("phone_numbers.index.page_title"), callthrough_phone_numbers_path(@parent) + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, callthrough_phone_number_path(@callthrough, @phone_number) + end + end + + if @parent.class == SipAccount + if @sip_account.sip_accountable.class == User + add_breadcrumb t("#{@sip_account.sip_accountable.class.name.underscore.pluralize}.index.page_title"), method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore.pluralize}_path" ).(@sip_account.tenant) + add_breadcrumb @sip_account.sip_accountable, method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore}_path" ).(@sip_account.tenant, @sip_account.sip_accountable) + end + add_breadcrumb t("sip_accounts.index.page_title"), method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_accounts_path" ).(@sip_account.sip_accountable) + add_breadcrumb @sip_account, method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_account_path" ).(@sip_account.sip_accountable, @sip_account) + add_breadcrumb t("phone_numbers.index.page_title"), sip_account_phone_numbers_path(@sip_account) + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, sip_account_phone_number_path(@sip_account, @phone_number) + end + end + + if @parent.class == Conference + @conference = @parent + conference_parent = @conference.conferenceable + if conference_parent && conference_parent.class == User + @user = conference_parent + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t("conferences.index.page_title"), user_conferences_path(@user) + add_breadcrumb @conference, user_conference_path(@user, @conference) + end + if conference_parent && conference_parent.class == Tenant + @tenant = conference_parent + add_breadcrumb t("conferences.index.page_title"), tenant_conferences_path(@tenant) + add_breadcrumb @conference, tenant_conference_path(@tenant, @conference) + end + add_breadcrumb t("phone_numbers.index.page_title"), conference_phone_numbers_path(@conference) + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, conference_phone_number_path(@conference, @phone_number) + end + end + + if @parent.class == HuntGroup + add_breadcrumb t("#{@parent.class.name.underscore.pluralize}.index.page_title"), tenant_hunt_groups_path(@parent.tenant) + add_breadcrumb @hunt_group, tenant_hunt_group_path(@parent.tenant, @hunt_group) + add_breadcrumb t("phone_numbers.index.page_title"), hunt_group_phone_numbers_path(@parent) + end + + if @parent.class == HuntGroupMember + add_breadcrumb t("hunt_groups.index.page_title"), tenant_hunt_groups_path(@parent.hunt_group.tenant) + add_breadcrumb @parent.hunt_group, tenant_hunt_group_path(@parent.hunt_group.tenant, @parent.hunt_group) + add_breadcrumb t("hunt_group_members.index.page_title"), hunt_group_hunt_group_members_path(@parent.hunt_group) + add_breadcrumb @parent, hunt_group_hunt_group_member_path(@parent.hunt_group, @parent) + add_breadcrumb t("phone_numbers.index.page_title"), hunt_group_member_phone_numbers_path(@parent) + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, hunt_group_member_phone_number_path(@parent, @phone_number) + end + end + + if @parent.class == AccessAuthorization + if @parent.access_authorizationable.class == Callthrough + callthrough = @parent.access_authorizationable + tenant = callthrough.tenant + add_breadcrumb t("callthroughs.index.page_title"), tenant_callthroughs_path(tenant) + add_breadcrumb callthrough, tenant_callthrough_path(tenant, callthrough) + add_breadcrumb t("access_authorizations.index.page_title"), callthrough_access_authorizations_path(callthrough) + add_breadcrumb @parent, callthrough_access_authorization_path(callthrough, @parent) + add_breadcrumb t("phone_numbers.index.page_title"), access_authorization_phone_numbers_path(@parent) + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, access_authorization_phone_number_path(@parent, @phone_number) + end + end + end + + if @parent.class == PhoneBookEntry + @phone_book = @parent.phone_book + if @parent.phone_book.phone_bookable.class == Tenant + @tenant = @parent.phone_book.phone_bookable + add_breadcrumb t("phone_books.index.page_title"), tenant_phone_books_path(@tenant) + add_breadcrumb @phone_book, tenant_phone_book_path(@tenant, @phone_book) + add_breadcrumb @phone_book_entry, phone_book_phone_book_entry_path(@phone_book, @phone_book_entry) + + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, phone_book_entry_phone_number_path(@phone_book_entry, @phone_number) + end + end + + if @parent.phone_book.phone_bookable.class == User + @user = @parent.phone_book.phone_bookable + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t("phone_books.index.page_title"), user_phone_books_path(@user) + add_breadcrumb @phone_book, user_phone_book_path(@user, @phone_book) + add_breadcrumb @phone_book_entry, phone_book_phone_book_entry_path(@phone_book, @phone_book_entry) + + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, phone_book_entry_phone_number_path(@phone_book_entry, @phone_number) + end + end + end + + if @parent.class == Whitelist + @tenant = @parent.whitelistable.tenant + @callthrough = @parent.whitelistable + @whitelist = @parent + add_breadcrumb t("callthroughs.name").pluralize, tenant_callthroughs_path(@tenant) + add_breadcrumb @callthrough, tenant_callthrough_path(@tenant, @callthrough) + add_breadcrumb t("whitelists.index.page_title"), callthrough_whitelists_path(@callthrough) + add_breadcrumb @whitelist, callthrough_whitelist_path(@callthrough, @whitelist) + add_breadcrumb t("phone_numbers.index.page_title"), whitelist_phone_numbers_path(@whitelist) + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, whitelist_phone_number_path(@whitelist, @phone_number) + end + end + + if @parent.class == AutomaticCallDistributor + if @automatic_call_distributor.automatic_call_distributorable.class == User + add_breadcrumb t("#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore.pluralize}.index.page_title"), method( :"tenant_#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore.pluralize}_path" ).(@automatic_call_distributor.tenant) + add_breadcrumb @automatic_call_distributor.automatic_call_distributorable, method( :"tenant_#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore}_path" ).(@automatic_call_distributor.tenant, @automatic_call_distributor.automatic_call_distributorable) + end + add_breadcrumb t("automatic_call_distributors.index.page_title"), method( :"#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore}_automatic_call_distributors_path" ).(@automatic_call_distributor.automatic_call_distributorable) + add_breadcrumb @automatic_call_distributor, method( :"#{@automatic_call_distributor.automatic_call_distributorable.class.name.underscore}_automatic_call_distributor_path" ).(@automatic_call_distributor.automatic_call_distributorable, @automatic_call_distributor) + add_breadcrumb t("phone_numbers.index.page_title"), automatic_call_distributor_phone_numbers_path(@automatic_call_distributor) + if @phone_number && !@phone_number.new_record? + add_breadcrumb @phone_number, automatic_call_distributor_phone_number_path(@automatic_call_distributor, @phone_number) + end + end + + end + +end diff --git a/app/controllers/phone_sip_accounts_controller.rb b/app/controllers/phone_sip_accounts_controller.rb new file mode 100644 index 0000000..8558c55 --- /dev/null +++ b/app/controllers/phone_sip_accounts_controller.rb @@ -0,0 +1,60 @@ +class PhoneSipAccountsController < ApplicationController + load_and_authorize_resource :phone + load_and_authorize_resource :phone_sip_account, :through => [:phone] + + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @available_sip_accounts = @phone.phoneable.sip_accounts + + # Ensure a SipAccount is used on a single phone only. + # + @available_sip_accounts = @available_sip_accounts.delete_if { |x| x.phone_sip_account_ids.count > 0 } + + if @available_sip_accounts.count == 0 + redirect_to method( :"new_#{@phone.phoneable.class.name.underscore}_sip_account_path" ).(@phone.phoneable), :alert => t('phone_sip_accounts.controller.no_existing_sip_accounts_warning') + else + @phone_sip_account = @phone.phone_sip_accounts.build(:sip_account_id => @available_sip_accounts.first.try(:id)) + end + end + + def create + @phone_sip_account = @phone.phone_sip_accounts.build(params[:phone_sip_account]) + if @phone_sip_account.save + redirect_to method( :"#{@phone_sip_account.phone.phoneable.class.name.underscore}_phone_path" ).(@phone_sip_account.phone.phoneable, @phone_sip_account.phone), :notice => t('phone_sip_accounts.controller.successfuly_created') + else + render :new + end + end + + def destroy + @phone_sip_account.destroy + redirect_to method( :"#{@phone_sip_account.phone.phoneable.class.name.underscore}_phone_path" ).(@phone_sip_account.phone.phoneable, @phone_sip_account.phone), :notice => t('phone_sip_accounts.controller.successfuly_destroyed') + end + + private + + def spread_breadcrumbs + if @phone.phoneable.class == User + user = @phone.phoneable + add_breadcrumb t('users.index.page_title'), tenant_users_path(user.current_tenant) + add_breadcrumb user, tenant_user_path(user.current_tenant, user) + add_breadcrumb t('phones.index.page_title'), user_phones_path(user) + elsif @phone.phoneable.class == Tenant + tenant = @phone.phoneable + add_breadcrumb t('phones.index.page_title'), tenant_phones_path(tenant) + end + add_breadcrumb @phone, method( :"#{@phone.phoneable.class.name.underscore}_phone_path" ).(@phone.phoneable, @phone) + add_breadcrumb t('phone_sip_accounts.index.page_title'), phone_phone_sip_accounts_path(@phone) + if @phone_sip_account && !@phone_sip_account.new_record? + add_breadcrumb @phone_sip_account, phone_phone_sip_account_path(@phone, @phone_sip_account) + end + end + +end diff --git a/app/controllers/phones_controller.rb b/app/controllers/phones_controller.rb new file mode 100644 index 0000000..d46bf86 --- /dev/null +++ b/app/controllers/phones_controller.rb @@ -0,0 +1,72 @@ +class PhonesController < ApplicationController + load_resource :tenant + load_resource :user + load_and_authorize_resource :phone, :through => [:tenant, :user] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @phone = @phoneable.phones.build() + + # Use the last phone.phone_model as the default. + # + @phone.phone_model_id = Phone.last.try(:phone_model).try(:id) + end + + def create + @phone = @phoneable.phones.build(params[:phone]) + if @phone.save + m = method( :"#{@phoneable.class.name.underscore}_phone_path" ) + redirect_to m.( @phoneable, @phone ), :notice => t('phones.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @phone.update_attributes(params[:phone]) + m = method( :"#{@phoneable.class.name.underscore}_phone_path" ) + redirect_to m.( @phoneable, @phone ), :notice => t('phones.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @phone.destroy + m = method( :"#{@phoneable.class.name.underscore}_phones_url" ) + redirect_to m.( @phoneable ), :notice => t('phones.controller.successfuly_destroyed') + end + + private + def set_and_authorize_parent + @phoneable = (@user || @tenant) + @parent = @phoneable + authorize! :read, @parent + @nesting_prefix = @phoneable ? "#{@phoneable.class.name.underscore}_" : '' + end + + def spread_breadcrumbs + if @user + add_breadcrumb t('users.index.page_title'), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t('phones.index.page_title'), user_phones_path(@user) + elsif @tenant + add_breadcrumb t('phones.index.page_title'), tenant_phones_path(@tenant) + end + if @phone && !@phone.new_record? + add_breadcrumb @phone, method( :"#{@phone.phoneable.class.name.underscore}_phone_path" ).(@phone.phoneable, @phone) + end + end + +end diff --git a/app/controllers/ringtones_controller.rb b/app/controllers/ringtones_controller.rb new file mode 100644 index 0000000..7ffe30e --- /dev/null +++ b/app/controllers/ringtones_controller.rb @@ -0,0 +1,67 @@ +class RingtonesController < ApplicationController + load_resource :phone_number + load_resource :boss_assistant_cooperation + load_and_authorize_resource :ringtone, :through => [:phone_number, :boss_assistant_cooperation] + + before_filter :set_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @ringtone = @parent.ringtones.build + end + + def create + @ringtone = @parent.ringtones.build(params[:ringtone]) + if @ringtone.save + redirect_to phone_number_ringtone_path(@parent, @ringtone), :notice => t('ringtones.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @ringtone.update_attributes(params[:ringtone]) + redirect_to method( :"#{@parent.class.name.underscore}_ringtone_path" ).(@ringtone.ringtoneable, @ringtone), :notice => t('ringtones.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @ringtone.destroy + redirect_to phone_number_ringtones_path(@parent), :notice => t('ringtones.controller.successfuly_destroyed') + end + + private + def set_parent + @parent = @phone_number || @boss_assistant_cooperation + end + + def spread_breadcrumbs + if @parent.class == PhoneNumber && @parent.phone_numberable.class == SipAccount + @sip_account = @parent.phone_numberable + if @sip_account.sip_accountable.class == User + add_breadcrumb t("#{@sip_account.sip_accountable.class.name.underscore.pluralize}.index.page_title"), method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore.pluralize}_path" ).(@sip_account.tenant) + add_breadcrumb @sip_account.sip_accountable, method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore}_path" ).(@sip_account.tenant, @sip_account.sip_accountable) + end + add_breadcrumb t("sip_accounts.index.page_title"), method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_accounts_path" ).(@sip_account.sip_accountable) + add_breadcrumb @sip_account, method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_account_path" ).(@sip_account.sip_accountable, @sip_account) + add_breadcrumb t("phone_numbers.index.page_title"), sip_account_phone_numbers_path(@sip_account) + add_breadcrumb @phone_number, sip_account_phone_number_path(@sip_account, @phone_number) + add_breadcrumb t("ringtones.index.page_title"), phone_number_ringtones_path(@phone_number) + if @ringtone && !@ringtone.new_record? + add_breadcrumb @ringtone, phone_number_ringtone_path(@phone_number, @ringtone) + end + end + end + +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..f92ae1c --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,44 @@ +class SessionsController < ApplicationController + + before_filter :redirect_to_https + skip_before_filter :home_breadcrumb + + def new + end + + def create + user = User.find_by_email(params[:sessions][:login_data].downcase.strip) + if user.nil? + user = User.find_by_user_name(params[:sessions][:login_data].downcase.strip) + end + if user && user.authenticate(params[:sessions][:password]) + session[:user_id] = user.id + redirect_to tenant_user_path(user.current_tenant, user), :notice => t('sessions.controller.successfully_created', :resource => user) + elsif user && !user.email.blank? && params[:sessions][:reset_password] =~ (/(1|t|y|yes|true)$/i) + password = SecureRandom.base64(8)[0..7] + if user.update_attributes(:password => password) + Notifications.new_password(user, password).deliver + flash.now.notice = t('sessions.flash_messages.password_recovery_successful', :resource => user) + else + flash.now.alert = t('sessions.flash_messages.password_recovery_failed', :resource => user) + end + render "new" + else + flash.now.alert = t('sessions.flash_messages.invalid_email_or_password', :resource => user) + render "new" + end + end + + def destroy + session[:user_id] = nil + redirect_to root_url, :notice => t('sessions.controller.successfully_destroyed') + end + + private + def redirect_to_https + if GUI_REDIRECT_HTTPS and ! request.ssl? + redirect_to :protocol => "https://" + end + end + +end diff --git a/app/controllers/sip_accounts_controller.rb b/app/controllers/sip_accounts_controller.rb new file mode 100644 index 0000000..1f3166e --- /dev/null +++ b/app/controllers/sip_accounts_controller.rb @@ -0,0 +1,98 @@ +class SipAccountsController < ApplicationController + load_resource :user + load_resource :tenant + load_and_authorize_resource :sip_account, :through => [:user, :tenant ] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @sip_account = @parent.sip_accounts.build + @sip_account.caller_name = @parent + @sip_account.call_waiting = CALL_WAITING + @sip_account.clir = DEFAULT_CLIR_SETTING + @sip_account.clip = DEFAULT_CLIP_SETTING + @sip_account.voicemail_pin = random_pin + @sip_account.callforward_rules_act_per_sip_account = CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT + @sip_account.hotdeskable = true + + # Make sure that we don't use an already taken auth_name + # + loop do + @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME) + + break unless SipAccount.exists?(:auth_name => @sip_account.auth_name) + end + @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD) + end + + def create + @sip_account = @parent.sip_accounts.build(params[:sip_account]) + + if @sip_account.auth_name.blank? + loop do + @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME) + + break unless SipAccount.exists?(:auth_name => @sip_account.auth_name) + end + end + if @sip_account.password.blank? + @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD) + end + + if @sip_account.save + m = method( :"#{@parent.class.name.underscore}_sip_account_path" ) + redirect_to m.( @parent, @sip_account ), :notice => t('sip_accounts.controller.successfuly_created', :resource => @parent) + else + render :new + end + end + + def edit + end + + def update + if @sip_account.update_attributes(params[:sip_account]) + m = method( :"#{@parent.class.name.underscore}_sip_account_path" ) + redirect_to m.( @parent, @sip_account ), :notice => t('sip_accounts.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @sip_account.destroy + m = method( :"#{@parent.class.name.underscore}_sip_accounts_url" ) + redirect_to m.( @parent ), :notice => t('sip_accounts.controller.successfuly_destroyed') + end + + private + def set_and_authorize_parent + @parent = @user || @tenant + authorize! :read, @parent + end + + def spread_breadcrumbs + if @user + add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t("sip_accounts.index.page_title"), user_sip_accounts_path(@user) + if @sip_account && !@sip_account.new_record? + add_breadcrumb @sip_account, user_sip_account_path(@user, @sip_account) + end + end + if @tenant + add_breadcrumb t("sip_accounts.index.page_title"), tenant_sip_accounts_path(@tenant) + if @sip_account && !@sip_account.new_record? + add_breadcrumb @sip_account, tenant_sip_account_path(@tenant, @sip_account) + end + end + end + +end diff --git a/app/controllers/sip_domains_controller.rb b/app/controllers/sip_domains_controller.rb new file mode 100644 index 0000000..7301192 --- /dev/null +++ b/app/controllers/sip_domains_controller.rb @@ -0,0 +1,41 @@ +class SipDomainsController < ApplicationController + def index + @sip_domains = SipDomain.all + end + + def show + @sip_domain = SipDomain.find(params[:id]) + end + + def new + @sip_domain = SipDomain.new + end + + def create + @sip_domain = SipDomain.new(params[:sip_domain]) + if @sip_domain.save + redirect_to @sip_domain, :notice => t('sip_domains.controller.successfuly_created') + else + render :new + end + end + + def edit + @sip_domain = SipDomain.find(params[:id]) + end + + def update + @sip_domain = SipDomain.find(params[:id]) + if @sip_domain.update_attributes(params[:sip_domain]) + redirect_to @sip_domain, :notice => t('sip_domains.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @sip_domain = SipDomain.find(params[:id]) + @sip_domain.destroy + redirect_to sip_domains_url, :notice => t('sip_domains.controller.successfuly_destroyed') + end +end diff --git a/app/controllers/softkeys_controller.rb b/app/controllers/softkeys_controller.rb new file mode 100644 index 0000000..d2a2bb9 --- /dev/null +++ b/app/controllers/softkeys_controller.rb @@ -0,0 +1,91 @@ +class SoftkeysController < ApplicationController + load_and_authorize_resource :sip_account + load_and_authorize_resource :softkey, :through => [:sip_account] + + before_filter :set_available_call_forwards_and_softkey_functions, :only => [ :new, :edit, :update ] + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @softkey = @sip_account.softkeys.build + + delete_call_forward_softkey_if_no_callforward_is_available + end + + def create + @softkey = @sip_account.softkeys.build(params[:softkey]) + if @softkey.save + redirect_to sip_account_softkey_path(@softkey.sip_account, @softkey), :notice => t('softkeys.controller.successfuly_created') + else + render :new + end + end + + def edit + delete_call_forward_softkey_if_no_callforward_is_available + end + + def update + if @softkey.update_attributes(params[:softkey]) + redirect_to sip_account_softkey_path(@softkey.sip_account, @softkey), :notice => t('softkeys.controller.successfuly_updated') + else + delete_call_forward_softkey_if_no_callforward_is_available + render :edit + end + end + + def destroy + @softkey.destroy + redirect_to sip_account_softkeys_path(@softkey.sip_account), :notice => t('softkeys.controller.successfuly_destroyed') + end + + def move_higher + @softkey.move_higher + redirect_to :back + end + + def move_lower + @softkey.move_lower + redirect_to :back + end + + private + + def set_available_call_forwards_and_softkey_functions + @available_call_forwards = @softkey.possible_blf_call_forwards + + @softkey_functions = [] + SoftkeyFunction.accessible_by(current_ability, :read).each do |softkey_function| + if GuiFunction.display?("softkey_function_#{softkey_function.name.downcase}_field_in_softkey_form", @current_user) + @softkey_functions << softkey_function + end + end + end + + def spread_breadcrumbs + if @sip_account.sip_accountable.class == User + add_breadcrumb t('users.name'), tenant_users_path(@sip_account.sip_accountable.current_tenant) + add_breadcrumb @sip_account.sip_accountable, tenant_user_path(@sip_account.sip_accountable.current_tenant, @sip_account.sip_accountable) + add_breadcrumb t('sip_accounts.index.page_title'), user_sip_accounts_path(@sip_account.sip_accountable) + add_breadcrumb @sip_account, user_sip_account_path(@sip_account.sip_accountable, @sip_account) + add_breadcrumb t('softkeys.index.page_title'), sip_account_softkeys_path(@sip_account) + elsif @sip_account.sip_accountable.class == Tenant + add_breadcrumb t('sip_accounts.index.page_title'), tenant_sip_accounts_path(@sip_account.sip_accountable) + add_breadcrumb @sip_account, tenant_sip_account_path(@sip_account.sip_accountable, @sip_account) + add_breadcrumb t('softkeys.index.page_title'), sip_account_softkeys_path(@sip_account) + end + end + + def delete_call_forward_softkey_if_no_callforward_is_available + # Don't display the call_forward option if there aren't any call_forwards to choose from. + # + if @softkey.sip_account.phone_numbers.map{|phone_number| phone_number.call_forwards}.flatten.count == 0 + @softkey_functions.delete_if { |softkey_function| softkey_function == SoftkeyFunction.find_by_name('call_forwarding') } + end + end +end diff --git a/app/controllers/system_messages_controller.rb b/app/controllers/system_messages_controller.rb new file mode 100644 index 0000000..d7fe515 --- /dev/null +++ b/app/controllers/system_messages_controller.rb @@ -0,0 +1,30 @@ +class SystemMessagesController < ApplicationController + load_and_authorize_resource :user + load_and_authorize_resource :system_message, :through => [:user] + + def index + @system_messages = @system_messages.where(:created_at => Time.now - 6.hours .. Time.now) + end + + def show + end + + def new + @system_message = @user.system_messages.build + end + + def create + @system_message = @user.system_messages.build(params[:system_message]) + if @system_message.save + # Push the new message via AJAX to the browser. + # + # PrivatePub.publish_to("/users/#{@system_message.user.id}/system_messages", + # "$('#system_message').empty();$('#system_message').append('<span class=\"created_at\">#{(I18n.l @system_message.created_at, :format => :short )}</span> #{@system_message.content}');$('#system_message_display').fadeIn();" + # ) + + redirect_to user_system_message_path(@user, @system_message), :notice => t('system_messages.controller.successfuly_created') + else + render :new + end + end +end diff --git a/app/controllers/tenants_controller.rb b/app/controllers/tenants_controller.rb new file mode 100644 index 0000000..724d179 --- /dev/null +++ b/app/controllers/tenants_controller.rb @@ -0,0 +1,91 @@ +class TenantsController < ApplicationController + load_and_authorize_resource :tenant + + def index + end + + def show + end + + def new + @tenant.name = generate_a_new_name(@tenant) + @tenant.sip_domain = SipDomain.last + @tenant.country = GemeinschaftSetup.first.country + @tenant.language = GemeinschaftSetup.first.language + @tenant.internal_extension_ranges = '10-99' + @tenant.from_field_voicemail_email = 'admin@localhost' + @tenant.from_field_pin_change_email = 'admin@localhost' + end + + def create + if @tenant.save + # Become a member of this tenant. + # + @tenant.tenant_memberships.create(:user_id => @current_user.id) + + # Groups + # + admin_group = @tenant.user_groups.create(:name => t('gemeinschaft_setups.initial_setup.admin_group_name')) + admin_group.users << @current_user + + user_group = @tenant.user_groups.create(:name => t('gemeinschaft_setups.initial_setup.user_group_name')) + user_group.users << @current_user + + @current_user.update_attributes!(:current_tenant_id => @tenant.id) + + # Generate the internal_extensions + # + if !@tenant.internal_extension_ranges.blank? + if @tenant.array_of_internal_extension_numbers.count < 105 + # This can be done more or less quick. + @tenant.generate_internal_extensions + else + # Better be on the save side and start a delayed job for this. + @tenant.delay.generate_internal_extensions + end + end + + # Generate the external numbers (DIDs) + # + if !@tenant.did_list.blank? + if @tenant.array_of_dids.count < 105 + # This can be done more or less quick. + @tenant.generate_dids + else + # Better be on the save side and start a delayed job for this. + @tenant.delay.generate_dids + end + end + + if Delayed::Job.count > 0 + redirect_to @tenant, :notice => t('tenants.controller.successfuly_created_plus_delayed_jobs', + :resource => @tenant, + :amount_of_numbers => @tenant.array_of_internal_extension_numbers.count + @tenant.array_of_dids.count + ) + else + redirect_to @tenant, :notice => t('tenants.controller.successfuly_created', + :resource => @tenant + ) + end + else + render :new + end + end + + def edit + end + + def update + if @tenant.update_attributes(params[:tenant]) + redirect_to @tenant, :notice => t('tenants.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @tenant.destroy + redirect_to tenants_url, :notice => t('tenants.controller.successfuly_destroyed') + end + +end diff --git a/app/controllers/user_group_memberships_controller.rb b/app/controllers/user_group_memberships_controller.rb new file mode 100644 index 0000000..1cbbd48 --- /dev/null +++ b/app/controllers/user_group_memberships_controller.rb @@ -0,0 +1,48 @@ +class UserGroupMembershipsController < ApplicationController + load_and_authorize_resource :user_group + load_and_authorize_resource :user_group_membership, :through => [:user_group] + + before_filter :spread_breadcrumbs + + def index + @potential_users_count = @user_group.tenant.users.count - @user_group.users.count + end + + def show + end + + def new + @user_group_membership = @user_group.user_group_memberships.build + @potential_users = (@user_group.tenant.users.order(:last_name) - @user_group.users) + if @potential_users.count == 0 + redirect_to user_group_user_group_memberships_path(@user_group), :alert => t('user_group_memberships.controller.no_more_user_to_add') + end + end + + def create + @user_group_membership = @user_group.user_group_memberships.build(params[:user_group_membership]) + if @user_group_membership.save + redirect_to user_group_user_group_membership_path(@user_group, @user_group_membership), :notice => t('user_group_memberships.controller.successfuly_created') + else + render :new + end + end + + def destroy + @user_group_membership.destroy + redirect_to user_group_user_group_memberships_path(@user_group), :notice => t('user_group_memberships.controller.successfuly_destroyed') + end + + private + + def spread_breadcrumbs + add_breadcrumb t("user_groups.index.page_title"), tenant_user_groups_path(@user_group.tenant) + add_breadcrumb @user_group, tenant_user_group_path(@user_group.tenant, @user_group) + add_breadcrumb t("user_group_memberships.index.page_title"), user_group_user_group_memberships_path(@user_group) + + if @user_group_membership && !@user_group_membership.new_record? + add_breadcrumb @user_group_membership, user_group_user_group_membership_path(@user_group, @user_group_membership) + end + end + +end diff --git a/app/controllers/user_groups_controller.rb b/app/controllers/user_groups_controller.rb new file mode 100644 index 0000000..158abaa --- /dev/null +++ b/app/controllers/user_groups_controller.rb @@ -0,0 +1,69 @@ +class UserGroupsController < ApplicationController + load_resource :tenant + load_resource :user + load_and_authorize_resource :user_group, :through => [:tenant, :user] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @user_group = @parent.user_groups.build + end + + def create + @user_group = @parent.user_groups.build(params[:user_group]) + if @user_group.save + redirect_to @user_group, :notice => t('user_groups.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @user_group.update_attributes(params[:user_group]) + redirect_to @user_group, :notice => t('user_groups.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @user_group.destroy + redirect_to user_groups_url, :notice => t('user_groups.controller.successfuly_destroyed') + end + + private + + def set_and_authorize_parent + @parent = @user || @tenant + authorize! :read, @parent + end + + def spread_breadcrumbs + if @tenant + add_breadcrumb t("user_groups.index.page_title"), tenant_user_groups_path(@tenant) + if @user_group && !@user_group.new_record? + add_breadcrumb @user_group, tenant_user_group_path(@tenant, @user_group) + end + end + + if @user + add_breadcrumb t("users.index.page_title"), tenant_users_path(@parent) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) + add_breadcrumb t("user_groups.index.page_title"), user_user_groups_path(@user) + if @user_group && !@user_group.new_record? + add_breadcrumb @user_group, user_user_group_path(@user, @user_group) + end + end + end + +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..454c26b --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,85 @@ +class UsersController < ApplicationController + load_resource :tenant + load_resource :user_group + load_and_authorize_resource :user, :through => [:tenant, :user_group] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + def index + end + + def show + @phone_books = PhoneBook.accessible_by( Ability.new( @user ) ).all + end + + def new + @user = @parent.users.build(params[:user]) + @user.male = true + @user.send_voicemail_as_email_attachment = true + end + + def create + @user = @parent.users.build(params[:user]) + if @user.save + if @parent.class == Tenant + @parent.tenant_memberships.create(:user => @user) + if @parent.user_groups.exists?(:name => 'Users') + @parent.user_groups.where(:name => 'Users').first.user_group_memberships.create(:user => @user) + end + redirect_to tenant_user_url( @parent, @user), :notice => t('users.controller.successfuly_created', :resource => @user) + else + redirect_to tenant_user_path(@user.current_tenant, @user), :notice => t('users.controller.successfuly_created_and_login', :resource => @user) + end + else + render :new + end + end + + def edit + end + + def update + if @user.update_attributes(params[:user]) + # Make sure that the flash notice gets rendered in the correct language. + I18n.locale = @user.language.code.downcase + + redirect_to tenant_user_path(@user.current_tenant, @user), :notice => t('users.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @user.destroy + redirect_to @parent, :notice => t('users.controller.successfuly_destroyed') + end + + def destroy_avatar + user = User.find(params[:user_id]) + user.remove_image = true # https://github.com/jnicklas/carrierwave/issues/360 + user.remove_image! + user.save + user.reload + user.image.remove! + user.save + redirect_to @parent, :notice => t('users.controller.avatar_destroyed') + end + + private + def set_and_authorize_parent + @parent = @tenant || @user_group + authorize! :read, @parent + end + + def spread_breadcrumbs + if @tenant + add_breadcrumb t("users.index.page_title"), tenant_users_path(@tenant) + + if @user && !@user.new_record? + add_breadcrumb @user, tenant_user_path(@tenant, @user) + end + end + end + +end diff --git a/app/controllers/voicemail_messages_controller.rb b/app/controllers/voicemail_messages_controller.rb new file mode 100644 index 0000000..58f5265 --- /dev/null +++ b/app/controllers/voicemail_messages_controller.rb @@ -0,0 +1,140 @@ +class VoicemailMessagesController < ApplicationController + + load_resource :sip_account + load_and_authorize_resource :voicemail_message, :through => [:sip_account] + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + before_filter { |controller| + if ! params[:type].blank? then + @type = params[:type].to_s + end + + if ! params[:page].blank? then + @pagination_page_number = params[:page].to_i + end + } + + def index + @messages_count = @sip_account.voicemail_messages.count + @messages_unread_count = @sip_account.voicemail_messages.where(:read_epoch => 0).count + @messages_read_count = @messages_count - @messages_unread_count + + if @type == 'read' + @voicemail_messages = @sip_account.voicemail_messages.where('read_epoch > 0').order('created_epoch DESC').paginate( + :page => @pagination_page_number, + :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE + ) + elsif @type == 'unread' + @voicemail_messages = @sip_account.voicemail_messages.where(:read_epoch => 0).order('created_epoch DESC').paginate( + :page => @pagination_page_number, + :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE + ) + else + @voicemail_messages = @sip_account.voicemail_messages.order('created_epoch DESC').paginate( + :page => @pagination_page_number, + :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE + ) + end + end + + def show + respond_to do |format| + format.wav { + if @voicemail_message.file_path + send_file @voicemail_message.file_path, :type => "audio/x-wav", + :filename => "#{Time.at(@voicemail_message.created_epoch).strftime('%Y%m%d-%H%M%S')}-#{@voicemail_message.cid_number}.wav" + else + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Message not found -->", + ) + end + } + end + end + + def new + end + + def create + end + + def edit + end + + def update + end + + def destroy + @voicemail_message.destroy + m = method( :"#{@parent.class.name.underscore}_voicemail_messages_url" ) + redirect_to m.(), :notice => t('voicemail_messages.controller.successfuly_destroyed') + end + + def destroy_multiple + result = false + if ! params[:selected_uuids].blank? then + voicemail_messages = @sip_account.voicemail_messages.where(:uuid => params[:selected_uuids]) + voicemail_messages.each do |voicemail_message| + result = voicemail_message.destroy + end + end + + m = method( :"#{@parent.class.name.underscore}_voicemail_messages_url" ) + if result + redirect_to m.(), :notice => t('voicemail_messages.controller.successfuly_destroyed') + else + redirect_to m.() + end + end + + def call + phone_number = @voicemail_message.cid_number + if ! phone_number.blank? && @sip_account.registration + @sip_account.call(phone_number) + end + redirect_to(:back) + end + + def mark_read + @voicemail_message.mark_read + redirect_to(:back) + end + + def mark_unread + @voicemail_message.mark_read(false) + redirect_to(:back) + end + + private + def set_and_authorize_parent + @parent = @sip_account + + authorize! :read, @parent + + @show_path_method = method( :"#{@parent.class.name.underscore}_voicemail_message_path" ) + @index_path_method = method( :"#{@parent.class.name.underscore}_voicemail_messages_path" ) + @new_path_method = method( :"new_#{@parent.class.name.underscore}_voicemail_message_path" ) + @edit_path_method = method( :"edit_#{@parent.class.name.underscore}_voicemail_message_path" ) + end + + def spread_breadcrumbs + if @parent.class == SipAccount + if @sip_account.sip_accountable.class == User + add_breadcrumb t("#{@sip_account.sip_accountable.class.name.underscore.pluralize}.index.page_title"), method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore.pluralize}_path" ).(@sip_account.tenant) + add_breadcrumb @sip_account.sip_accountable, method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore}_path" ).(@sip_account.tenant, @sip_account.sip_accountable) + end + add_breadcrumb t("sip_accounts.index.page_title"), method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_accounts_path" ).(@sip_account.sip_accountable) + add_breadcrumb @sip_account, method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_account_path" ).(@sip_account.sip_accountable, @sip_account) + add_breadcrumb t("voicemail_messages.index.page_title"), sip_account_voicemail_messages_path(@sip_account) + if @voicemail_message && !@voicemail_message.new_record? + add_breadcrumb @voicemail_message, sip_account_voicemail_message_path(@sip_account, @voicemail_message) + end + end + end + +end diff --git a/app/controllers/voicemail_settings_controller.rb b/app/controllers/voicemail_settings_controller.rb new file mode 100644 index 0000000..d31de8f --- /dev/null +++ b/app/controllers/voicemail_settings_controller.rb @@ -0,0 +1,91 @@ +class VoicemailSettingsController < ApplicationController + load_resource :sip_account + load_and_authorize_resource :voicemail_setting, :through => :sip_account, :singleton => true + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + before_filter :voicemail_defaults, :only => [:index, :show, :new, :create, :edit] + + def index + render :edit + end + + def show + render :edit + end + + def new + render :edit + end + + def create + @sip_account = SipAccount.where(:id => params[:sip_account_id]).first + params[:voicemail_setting][:username] = @sip_account.auth_name + params[:voicemail_setting][:domain] = @sip_account.sip_domain.try(:host) + @voicemail_setting = VoicemailSetting.new(params[:voicemail_setting]) + if @voicemail_setting.save + redirect_to sip_account_voicemail_settings_path(@sip_account), :notice => t('voicemail_settings.controller.successfuly_created') + else + render :action => 'edit' + end + end + + def edit + + end + + def update + if @voicemail_setting.update_attributes(params[:voicemail_setting]) + redirect_to sip_account_voicemail_settings_path(@sip_account), :notice => t('voicemail_settings.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + + end + + private + def set_and_authorize_parent + @parent = @sip_account + + authorize! :read, @parent + + @show_path_method = method( :"#{@parent.class.name.underscore}_voicemail_setting_path" ) + @index_path_method = method( :"#{@parent.class.name.underscore}_voicemail_settings_path" ) + @new_path_method = method( :"new_#{@parent.class.name.underscore}_voicemail_setting_path" ) + @edit_path_method = method( :"edit_#{@parent.class.name.underscore}_voicemail_setting_path" ) + end + + def spread_breadcrumbs + if @parent.class == SipAccount + if @sip_account.sip_accountable.class == User + add_breadcrumb t("#{@sip_account.sip_accountable.class.name.underscore.pluralize}.index.page_title"), method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore.pluralize}_path" ).(@sip_account.tenant) + add_breadcrumb @sip_account.sip_accountable, method( :"tenant_#{@sip_account.sip_accountable.class.name.underscore}_path" ).(@sip_account.tenant, @sip_account.sip_accountable) + end + add_breadcrumb t("sip_accounts.index.page_title"), method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_accounts_path" ).(@sip_account.sip_accountable) + add_breadcrumb @sip_account, method( :"#{@sip_account.sip_accountable.class.name.underscore}_sip_account_path" ).(@sip_account.sip_accountable, @sip_account) + add_breadcrumb t("voicemail_settings.index.page_title"), sip_account_voicemail_settings_path(@sip_account) + end + end + + def voicemail_defaults + path = "/opt/freeswitch/storage/voicemail/default/#{@sip_account.sip_domain.host}/#{@sip_account.auth_name}/" + @greeting_files = Dir.glob("#{path}*greeting*.wav").collect {|r| [ File.basename(r), File.expand_path(r) ] } + @name_files = Dir.glob("#{path}*name*.wav").collect {|r| [ File.basename(r), File.expand_path(r) ] } + + if @voicemail_setting.blank? then + @voicemail_setting = @sip_account.voicemail_setting + end + + if @voicemail_setting.blank? + @voicemail_setting = VoicemailSetting.new + @voicemail_setting.notify = true + @voicemail_setting.attachment = true + @voicemail_setting.mark_read = true + @voicemail_setting.purge = false + end + end + +end diff --git a/app/controllers/whitelists_controller.rb b/app/controllers/whitelists_controller.rb new file mode 100644 index 0000000..0526844 --- /dev/null +++ b/app/controllers/whitelists_controller.rb @@ -0,0 +1,61 @@ +class WhitelistsController < ApplicationController + load_and_authorize_resource :callthrough + load_and_authorize_resource :whitelist, :through => [:callthrough] + + before_filter :set_parent_and_path_methods + before_filter :spread_breadcrumbs + + def index + end + + def show + end + + def new + @whitelist.phone_numbers.build + end + + def create + @whitelist = @parent.whitelists.build(params[:whitelist]) + if @whitelist.save + redirect_to @show_path_method.(@parent, @whitelist), :notice => t('whitelists.controller.successfuly_created') + else + render :new + end + end + + def edit + end + + def update + if @whitelist.update_attributes(params[:whitelist]) + redirect_to @show_path_method.(@parent, @whitelist), :notice => t('whitelists.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @whitelist.destroy + redirect_to @index_path_method.(@parent), :notice => t('whitelists.controller.successfuly_destroyed') + end + + private + + def set_parent_and_path_methods + @parent = @callthrough + @show_path_method = method( :"#{@parent.class.name.underscore}_whitelist_path" ) + @index_path_method = method( :"#{@parent.class.name.underscore}_whitelists_path" ) + @new_path_method = method( :"new_#{@parent.class.name.underscore}_whitelist_path" ) + @edit_path_method = method( :"edit_#{@parent.class.name.underscore}_whitelist_path" ) + end + + def spread_breadcrumbs + if @parent && @parent.class == Callthrough + add_breadcrumb t("#{@parent.class.name.underscore.pluralize}.name").pluralize, tenant_callthroughs_path(@parent.tenant) + add_breadcrumb @callthrough, tenant_callthrough_path(@parent.tenant, @callthrough) + add_breadcrumb t("whitelists.index.page_title"), callthrough_whitelists_path(@parent) + end + end + +end |