diff options
24 files changed, 285 insertions, 53 deletions
diff --git a/app/controllers/acd_agents_controller.rb b/app/controllers/acd_agents_controller.rb index 4c08f68..e2aabdf 100644 --- a/app/controllers/acd_agents_controller.rb +++ b/app/controllers/acd_agents_controller.rb @@ -1,7 +1,7 @@ class AcdAgentsController < ApplicationController - load_and_authorize_resource :automatic_call_distributor - load_and_authorize_resource :acd_agent, :through => [:automatic_call_distributor] - + load_and_authorize_resource :automatic_call_distributor, :except => [:toggle] + load_and_authorize_resource :acd_agent, :through => [:automatic_call_distributor], :except => [:toggle] + load_and_authorize_resource :acd_agent, :only => [:toggle] before_filter :spread_breadcrumbs def index @@ -62,16 +62,24 @@ class AcdAgentsController < ApplicationController redirect_to automatic_call_distributor_acd_agents_path(@automatic_call_distributor), :notice => t('acd_agents.controller.successfuly_destroyed') end + def toggle + @acd_agent.toggle_status + redirect_to request.referer + end + + private 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) + if @automatic_call_distributor + 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 end diff --git a/app/controllers/calls_controller.rb b/app/controllers/calls_controller.rb index 9d85a10..6182ad8 100644 --- a/app/controllers/calls_controller.rb +++ b/app/controllers/calls_controller.rb @@ -31,7 +31,7 @@ class CallsController < ApplicationController end def create - @call = @sip_account.calls.create(params[:call]) + @call = @sip_account.call_legs.build(params[:call]) if @call && @call.call m = method( :"#{@parent.class.name.underscore}_calls_url" ) diff --git a/app/controllers/softkeys_controller.rb b/app/controllers/softkeys_controller.rb index 9179d8c..6727de1 100644 --- a/app/controllers/softkeys_controller.rb +++ b/app/controllers/softkeys_controller.rb @@ -2,7 +2,7 @@ class SoftkeysController < ApplicationController load_and_authorize_resource :sip_account, :except => [:sort] load_and_authorize_resource :softkey, :through => [:sip_account], :except => [:sort] - before_filter :set_available_softkey_functions, :only => [ :new, :edit, :update ] + before_filter :set_available_softkey_functions, :only => [ :new, :edit, :update, :create ] before_filter :spread_breadcrumbs, :except => [:sort] def index @@ -35,6 +35,7 @@ class SoftkeysController < ApplicationController 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 diff --git a/app/models/ability.rb b/app/models/ability.rb index 3cd1d4d..fe67547 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -170,6 +170,11 @@ class Ability can :manage, Ringtone, :ringtoneable_type => 'SipAccount', :ringtoneable_id => user.sip_account_ids can :create, Ringtone + # User can read and toggle status of ACD agents + # + can :read, AcdAgent, :destination_type => 'SipAccount', :destination_id => user.sip_account_ids + can :toggle, AcdAgent, :destination_type => 'SipAccount', :destination_id => user.sip_account_ids + # SoftkeyFunctions # can :read, SoftkeyFunction diff --git a/app/models/acd_agent.rb b/app/models/acd_agent.rb index 4be4700..61899f8 100644 --- a/app/models/acd_agent.rb +++ b/app/models/acd_agent.rb @@ -20,6 +20,15 @@ class AcdAgent < ActiveRecord::Base self.name || I18n.t('acd_agents.name') + ' ID ' + self.id.to_s end + def toggle_status + if self.status == 'active' + self.status = 'inactive' + else + self.status = 'active' + end + return self.save + end + private def set_presence dialplan_function = nil diff --git a/app/models/automatic_call_distributor.rb b/app/models/automatic_call_distributor.rb index 5807757..b9d7c51 100644 --- a/app/models/automatic_call_distributor.rb +++ b/app/models/automatic_call_distributor.rb @@ -5,6 +5,8 @@ class AutomaticCallDistributor < ActiveRecord::Base has_many :acd_agents, :dependent => :destroy has_many :phone_numbers, :as => :phone_numberable, :dependent => :destroy + has_many :call_forwards, :as => :call_forwardable, :dependent => :destroy + accepts_nested_attributes_for :phone_numbers, :reject_if => lambda { |phone_number| phone_number[:number].blank? }, :allow_destroy => true diff --git a/app/models/hunt_group.rb b/app/models/hunt_group.rb index 7338606..93279ae 100644 --- a/app/models/hunt_group.rb +++ b/app/models/hunt_group.rb @@ -2,7 +2,8 @@ class HuntGroup < ActiveRecord::Base attr_accessible :name, :strategy, :seconds_between_jumps, :phone_numbers_attributes belongs_to :tenant, :touch => true - has_many :call_forwards, :as => :destinationable, :dependent => :destroy + has_many :destrination_call_forwards, :as => :destinationable, :dependent => :destroy + has_many :call_forwards, :as => :call_forwardable, :dependent => :destroy validates_uniqueness_of :name, :scope => :tenant_id, :allow_nil => true, :allow_blank => true diff --git a/app/models/intruder.rb b/app/models/intruder.rb index 9a1c39a..9c01634 100644 --- a/app/models/intruder.rb +++ b/app/models/intruder.rb @@ -50,6 +50,27 @@ class Intruder < ActiveRecord::Base } end + def perimeter_db_rescan + Intruder.perimeter_control(:db_rescan, :key => self.key) + end + + def self.perimeter_db_rescan(key=nil) + Intruder.perimeter_control(:db_rescan, :key => key) + end + + def self.perimeter_control(action, attributes={}) + require 'freeswitch_event' + event = FreeswitchEvent.new('CUSTOM') + event.add_header('Event-Subclass', 'perimeter::control') + event.add_header('action', action) + attributes.each do |name, value| + if !name.blank? && value then + event.add_header(name, value) + end + end + return event.fire() + end + private def set_key_if_empty if self.key.blank? @@ -98,6 +119,7 @@ class Intruder < ActiveRecord::Base write_firewall_list restart_firewall end + self.perimeter_db_rescan end end @@ -108,6 +130,7 @@ class Intruder < ActiveRecord::Base restart_firewall end end + self.perimeter_db_rescan end def check_if_delete_relevant @@ -117,5 +140,6 @@ class Intruder < ActiveRecord::Base restart_firewall end end + self.perimeter_db_rescan end end diff --git a/app/models/sip_account.rb b/app/models/sip_account.rb index 74a2562..930069d 100644 --- a/app/models/sip_account.rb +++ b/app/models/sip_account.rb @@ -41,6 +41,7 @@ class SipAccount < ActiveRecord::Base has_many :call_legs, :class_name => 'Call' has_many :b_call_legs, :class_name => 'Call', :foreign_key => 'b_sip_account_id' + has_many :acd_agents, :as => :destination, :dependent => :destroy has_many :switchboard_entries, :dependent => :destroy # Delegations: @@ -162,12 +163,16 @@ class SipAccount < ActiveRecord::Base ); end - - def target_sip_accounts_by_permission(permission) + def target_group_ids_by_permission(permission) target_groups = Group.union(self.groups.collect{|g| g.permission_targets(permission)}) target_groups = target_groups + Group.union(self.sip_accountable.groups.collect{|g| g.permission_targets(permission)}) + + return target_groups + end + + def target_sip_accounts_by_permission(permission) sip_accounts = [] - GroupMembership.where(:group_id => target_groups).each do |group_membership| + GroupMembership.where(:group_id => target_group_ids_by_permission(permission)).each do |group_membership| if group_membership.item.class == User || group_membership.item.class == Tenant sip_accounts = sip_accounts + group_membership.item.sip_accounts elsif group_membership.item.class == SipAccount @@ -180,6 +185,33 @@ class SipAccount < ActiveRecord::Base return sip_accounts end + def status + states = Array.new + + SipAccount.last.call_legs.each do |call_leg| + states << { + :status => call_leg.callstate, + :caller => true, + :endpoint_name => call_leg.callee_name, + :endpoint_number => call_leg.destination, + :endpoint_sip_account_id => call_leg.b_sip_account_id, + :start_stamp => call_leg.start_stamp, + } + end + + SipAccount.last.b_call_legs.each do |call_leg| + states << { + :status => call_leg.callstate, + :caller => false, + :endpoint_name => call_leg.caller_id_name, + :endpoint_number => call_leg.caller_id_number, + :endpoint_sip_account_id => call_leg.sip_account_id, + :start_stamp => call_leg.start_stamp, + } + end + + return states + end private diff --git a/app/models/softkey.rb b/app/models/softkey.rb index 6063017..7f77a25 100644 --- a/app/models/softkey.rb +++ b/app/models/softkey.rb @@ -1,17 +1,17 @@ class Softkey < ActiveRecord::Base - attr_accessible :softkey_function_id, :number, :label, :uuid, :softkeyable_type, :softkeyable_id + attr_accessible :softkey_function_id, :number, :label, :uuid, :softkeyable_type, :softkeyable_id, :call_forward, :blf belongs_to :sip_account belongs_to :softkey_function belongs_to :softkeyable, :polymorphic => true - validates_presence_of :softkeyable_id, :if => Proc.new{ |softkey| self.softkey_function_id != nil && - self.softkey_function_id == SoftkeyFunction.find_by_name('call_forwarding').try(:id) } - # These functions need a number to act. # validates_presence_of :number, :if => Proc.new{ |softkey| self.softkey_function_id != nil && - ['blf','speed_dial','dtmf','conference'].include?(softkey.softkey_function.name) } + ['blf', 'speed_dial','dtmf','conference'].include?(softkey.softkey_function.name) } + + validates_presence_of :softkeyable_id, :if => Proc.new{ |softkey| self.softkey_function_id != nil && + ['call_forwarding'].include?(softkey.softkey_function.name) } validates_presence_of :uuid validates_uniqueness_of :uuid @@ -43,7 +43,16 @@ class Softkey < ActiveRecord::Base end def possible_blf_sip_accounts - self.sip_account.target_sip_accounts_by_permission('presence') + self.sip_account.target_sip_accounts_by_permission(:presence) + end + + def possible_pickup_groups + Group.where(:id => self.sip_account.target_group_ids_by_permission(:presence)) + end + + def possible_blf + blf = possible_pickup_groups.collect{ |g| ["#{g.class.name}: #{g.to_s}", "#{g.id}:#{g.class.name}"] } + blf + possible_blf_sip_accounts.collect{ |g| ["#{g.class.name}: #{g.to_s}", "#{g.id}:#{g.class.name}"] } end def to_s @@ -73,6 +82,7 @@ class Softkey < ActiveRecord::Base return self.position.to_i < Softkey.where(:sip_account_id => self.sip_account_id ).order(:position).last.position.to_i end + private # Make sure that no number is set when there is no need for one. # And make sure that there is no CallForward connected when not needed. diff --git a/app/views/acd_agents/_index_core.html.haml b/app/views/acd_agents/_index_core.html.haml index c8967cd..f1172f2 100644 --- a/app/views/acd_agents/_index_core.html.haml +++ b/app/views/acd_agents/_index_core.html.haml @@ -1,8 +1,8 @@ %table.table.table-striped %thead %tr + %th %th= t('acd_agents.index.name') - %th= t('acd_agents.index.status') %th= t('acd_agents.index.last_call') %th= t('acd_agents.index.calls_answered') %th= t('acd_agents.index.destination') @@ -10,8 +10,17 @@ %tbody - for acd_agent in acd_agents %tr + %td + - if acd_agent.status == 'active' + %a.btn.btn-small.btn-success{ :href => toggle_acd_agent_path(acd_agent) } + %i.icon-ok.icon-white + - elsif acd_agent.status == 'inactive' + %a.btn.btn-small.btn-danger{ :href => toggle_acd_agent_path(acd_agent) } + %i.icon-ban-circle.icon-white + - else + %a.btn.btn-small.btn-warning{ :href => toggle_acd_agent_path(acd_agent) } + = acd_agent.status %td= acd_agent.name - %td= acd_agent.status %td= acd_agent.last_call %td= acd_agent.calls_answered %td= acd_agent.destination diff --git a/app/views/automatic_call_distributors/show.html.haml b/app/views/automatic_call_distributors/show.html.haml index a461652..18fd8b8 100644 --- a/app/views/automatic_call_distributors/show.html.haml +++ b/app/views/automatic_call_distributors/show.html.haml @@ -63,6 +63,13 @@ = render 'phone_numbers/index_core', :phone_numbers => @automatic_call_distributor.phone_numbers = render :partial => 'shared/create_link', :locals => {:parent => @automatic_call_distributor, :child_class => PhoneNumber, :short_link => true} +- if @automatic_call_distributor.call_forwards.count > 0 || can?(:create, @automatic_call_distributor.call_forwards.build) + %h3= t('call_forwards.index.page_title') + - if @automatic_call_distributor.call_forwards.count > 0 + = render "call_forwards/index_core", :call_forwards => @automatic_call_distributor.call_forwards + %br + = render :partial => 'shared/create_link', :locals => { :parent => @automatic_call_distributor, :child_class => CallForward } + - if can?( :index, @automatic_call_distributor.acd_agents ) %h3= t('automatic_call_distributors.index.acd_agents') = render 'acd_agents/index_core', :acd_agents => @automatic_call_distributor.acd_agents diff --git a/app/views/hunt_groups/show.html.haml b/app/views/hunt_groups/show.html.haml index 3ffe4f3..99eb3e0 100644 --- a/app/views/hunt_groups/show.html.haml +++ b/app/views/hunt_groups/show.html.haml @@ -19,6 +19,13 @@ %br = render :partial => 'shared/create_link', :locals => {:parent => @hunt_group, :child_class => PhoneNumber} +- if @hunt_group.call_forwards.count > 0 || can?(:create, @hunt_group.call_forwards.build) + %h2= t('call_forwards.index.page_title') + - if @hunt_group.call_forwards.count > 0 + = render "call_forwards/index_core", :call_forwards => @hunt_group.call_forwards + %br + = render :partial => 'shared/create_link', :locals => { :parent => @hunt_group, :child_class => CallForward } + %h2= t('hunt_groups.form.hunt_group_members.label') - if @hunt_group.hunt_group_members.count > 0 = render 'hunt_group_members/index_core', :hunt_group_members => @hunt_group.hunt_group_members diff --git a/app/views/sip_accounts/show.html.haml b/app/views/sip_accounts/show.html.haml index 365aea8..9f84c92 100644 --- a/app/views/sip_accounts/show.html.haml +++ b/app/views/sip_accounts/show.html.haml @@ -99,3 +99,10 @@ - if @sip_account.calls.count > 0 %h2= t("calls.index.page_title") = render "calls/index_core", :calls => @sip_account.calls, :parent => @sip_account + +- if (can?(:read, AcdAgent) && @sip_account.acd_agents.count > 0) || can?(:create, @sip_account.acd_agents.build) + %h2= t('acd_agents.index.page_title') + - if @sip_account.acd_agents.count > 0 + = render "acd_agents/index_core", :acd_agents => @sip_account.acd_agents + %br + = render :partial => 'shared/create_link', :locals => { :parent => @sip_account, :child_class => AcdAgent } diff --git a/app/views/softkeys/_form_core.html.haml b/app/views/softkeys/_form_core.html.haml index f447aa6..0e251f3 100644 --- a/app/views/softkeys/_form_core.html.haml +++ b/app/views/softkeys/_form_core.html.haml @@ -4,10 +4,11 @@ hold_function_name = "#{I18n.t('softkeys.functions.hold')}" deactivated_function_name = "#{I18n.t('softkeys.functions.deactivated')}" + .inputs = f.input :softkey_function_id, :as => :select, :collection => @softkey_functions.map {|x| [I18n.t("softkeys.functions.#{x}"), x.id] }, :label => t('softkeys.form.function.label'), :hint => conditional_hint('softkeys.form.function.hint'), :include_blank => false - call_forwards = @softkey.possible_call_forwards - if call_forwards && call_forwards.count > 0 - = f.association :softkeyable, :collection => call_forwards, :label => t('softkeys.form.call_forward.label'), :hint => conditional_hint('softkeys.form.call_forward.hint'), :include_blank => false + = f.input :softkeyable_id, :collection => call_forwards, :label => t('softkeys.form.call_forward.label'), :hint => conditional_hint('softkeys.form.call_forward.hint'), :include_blank => false = f.input :number, :label => t('softkeys.form.number.label'), :hint => conditional_hint('softkeys.form.number.hint') = f.input :label, :label => t('softkeys.form.label.label'), :hint => conditional_hint('softkeys.form.label.hint') diff --git a/config/routes.rb b/config/routes.rb index cfee51b..976bac8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -63,13 +63,17 @@ Gemeinschaft42c::Application.routes.draw do collection { post :sort } end - resources :acd_agents, :only => [] do + resources :acd_agents do resources :phone_numbers + member do + get 'toggle' + end end resources :automatic_call_distributors, :only => [] do resources :acd_agents resources :phone_numbers + resources :call_forwards end resources :hunt_group_members, :only => [] do @@ -79,6 +83,7 @@ Gemeinschaft42c::Application.routes.draw do resources :hunt_groups, :only => [] do resources :hunt_group_members resources :phone_numbers + resources :call_forwards end if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true @@ -267,6 +272,7 @@ Gemeinschaft42c::Application.routes.draw do resources :call_forwards resources :ringtones resources :calls + resources :acd_agents resources :call_histories do collection do delete 'destroy_multiple' diff --git a/db/migrate/20130309055700_change_perimeter_gs_parameters.rb b/db/migrate/20130309055700_change_perimeter_gs_parameters.rb new file mode 100644 index 0000000..6e29bd0 --- /dev/null +++ b/db/migrate/20130309055700_change_perimeter_gs_parameters.rb @@ -0,0 +1,18 @@ +class ChangePerimeterGsParameters < ActiveRecord::Migration + def up + GsParameter.where(:entity => 'perimeter', :section => 'bad_headers_register', :name => 'from_user').first.update_attributes(:value => '^%d+$', :class_type => 'String') + GsParameter.where(:entity => 'perimeter', :section => 'bad_headers_register', :name => 'to_user').first.update_attributes(:value => '^%d+$', :class_type => 'String') + + GsParameter.where(:entity => 'perimeter', :section => 'checks_call', :name => 'check_bad_headers').first.update_attributes(:value => '20', :class_type => 'Integer') + GsParameter.where(:entity => 'perimeter', :section => 'checks_call', :name => 'check_frequency').first.update_attributes(:value => '100', :class_type => 'Integer') + + GsParameter.where(:entity => 'perimeter', :section => 'checks_register', :name => 'check_bad_headers').first.update_attributes(:value => '20', :class_type => 'Integer') + GsParameter.where(:entity => 'perimeter', :section => 'checks_register', :name => 'check_frequency').first.update_attributes(:value => '100', :class_type => 'Integer') + GsParameter.where(:entity => 'perimeter', :section => 'checks_register', :name => 'check_username_scan').first.update_attributes(:value => '20', :class_type => 'Integer') + + GsParameter.where(:entity => 'perimeter', :section => 'general', :name => 'ban_threshold').first.update_attributes(:value => '1000', :class_type => 'Integer') + end + + def down + end +end diff --git a/misc/freeswitch/conf/freeswitch.xml b/misc/freeswitch/conf/freeswitch.xml index f72651f..a2c2bf5 100644 --- a/misc/freeswitch/conf/freeswitch.xml +++ b/misc/freeswitch/conf/freeswitch.xml @@ -914,7 +914,6 @@ <match> <action function="play-file" data="ivr/ivr-you_are_number.wav"/> <action function="say" data="$1" method="pronounced" type="number"/> - <action function="play-file" data="ivr/ivr-in_line.wav"/> </match> </input> </macro> @@ -923,7 +922,6 @@ <match> <action function="play-file" data="ivr/ivr-you_are_number.wav"/> <action function="say" data="1" method="pronounced" type="number"/> - <action function="play-file" data="ivr/ivr-in_line.wav"/> <action function="break"/> </match> </input> @@ -931,7 +929,6 @@ <match> <action function="play-file" data="ivr/ivr-you_are_number.wav"/> <action function="say" data="$1" method="pronounced" type="number"/> - <action function="play-file" data="ivr/ivr-in_line.wav"/> <action function="play-file" data="ivr/ivr-thank_you_for_holding.wav"/> </match> </input> @@ -941,7 +938,6 @@ <match> <action function="play-file" data="ivr/ivr-you_are_number.wav"/> <action function="say" data="1" method="pronounced" type="number"/> - <action function="play-file" data="ivr/ivr-in_line.wav"/> <action function="break"/> </match> </input> @@ -949,7 +945,6 @@ <match> <action function="play-file" data="ivr/ivr-you_are_number.wav"/> <action function="say" data="$1" method="pronounced" type="number"/> - <action function="play-file" data="ivr/ivr-in_line.wav"/> <action function="play-file" data="ivr/ivr-thank_you_for_holding.wav"/> </match> </input> diff --git a/misc/freeswitch/scripts/common/intruder.lua b/misc/freeswitch/scripts/common/intruder.lua index 083ec37..7d12155 100644 --- a/misc/freeswitch/scripts/common/intruder.lua +++ b/misc/freeswitch/scripts/common/intruder.lua @@ -49,3 +49,46 @@ function Intruder.update_blacklist(self, event) self.database:insert_or_update('intruders', intruder_record, { created_at = false, comment = false }); end + + +function Intruder.sources_list(self, key) + local sql_query = nil; + + if key then + sql_query = 'SELECT * FROM `intruders` WHERE `key` = ' .. self.database:escape(key, '"') .. ' LIMIT 1'; + else + sql_query = 'SELECT * FROM `intruders`'; + end + + local sources = {}; + local sources_count = 0; + local blacklist_count = 0; + local whitelist_count = 0; + + self.database:query(sql_query, function(record) + sources[record.key] = { + ignore = (record.list_type == 'whitelist'), + contact_first = 0, + contact_last = 0, + contact_count = tonumber(record.contact_count) or 0, + span_contact_count = 0, + span_start = 0, + points = tonumber(record.points) or 0, + banned = tonumber(record.bans) or 0, + }; + sources_count = sources_count + 1; + if record.list_type == 'whitelist' then + whitelist_count = whitelist_count + 1; + elseif record.list_type == 'blacklist' then + blacklist_count = blacklist_count + 1; + end + end); + + self.log:info('[intruder] INTRUDER_LIST - entries loaded: ', sources_count, ', blacklist: ', blacklist_count, ', whitelist: ', whitelist_count); + + if key then + return sources[key]; + end + + return sources; +end diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua index 0815d33..8ad38d3 100644 --- a/misc/freeswitch/scripts/common/perimeter.lua +++ b/misc/freeswitch/scripts/common/perimeter.lua @@ -94,12 +94,24 @@ end function Perimeter.check(self, event) - if not event or not event.key then - self.log:warning('[perimeter] PERIMETER_CHECK - no event/key'); + if not type(event) == 'list' then + self.log:warning('[perimeter] PERIMETER_CHECK - no event data'); + return; + end + if not event.key then + self.log:warning('[perimeter] PERIMETER_CHECK - no key'); + for key, value in pairs() do + self.log:debug('[perimeter] PERIMETER_CHECK event_data - "', key, '" = "', value, '"'); + end return; end - event.record = self:record_load(event); + event.record = self:record_load(event); + + if event.record.ignore then + return + end + if event.record.banned <= self.ban_tries then for check_name, check_points in pairs(self.checks[event.action]) do if self.checks_available[check_name] then @@ -239,3 +251,17 @@ function Perimeter.expand_variables(self, line, variables) return variables[captured] or ''; end)) end + + +function Perimeter.action_db_rescan(self, record) + require 'common.str'; + require 'common.intruder'; + + if common.str.blank(record.key) then + self.log:info('[perimeter] PERIMETER rescan entire sources database'); + self.sources = common.intruder.Intruder:new{ log = self.log, database = self.database }:sources_list(); + else + self.log:info('[perimeter] PERIMETER rescan sources database - key: ', record.key); + self.sources[record.key] = common.intruder.Intruder:new{ log = self.log, database = self.database }:sources_list(record.key); + end +end diff --git a/misc/freeswitch/scripts/common/sip_account.lua b/misc/freeswitch/scripts/common/sip_account.lua index 6cc7d25..e7ee0d7 100644 --- a/misc/freeswitch/scripts/common/sip_account.lua +++ b/misc/freeswitch/scripts/common/sip_account.lua @@ -130,9 +130,9 @@ end function SipAccount.call_state(self) - local sql_query = 'SELECT `callstate` FROM `detailed_calls` \ - WHERE `presence_id` LIKE "' .. self.record.auth_name .. '@%" \ - OR `b_presence_id` LIKE "' .. self.record.auth_name .. '@%" \ + local sql_query = 'SELECT `callstate` FROM `calls_active` \ + WHERE `sip_account_id` = ' .. self.id .. ' \ + OR `b_sip_account_id` = ' .. self.id .. ' \ LIMIT 1'; return self.database:query_return_value(sql_query); diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index ffad4da..4cc2245 100644 --- a/misc/freeswitch/scripts/dialplan/dialplan.lua +++ b/misc/freeswitch/scripts/dialplan/dialplan.lua @@ -579,13 +579,17 @@ end function Dialplan.voicemail(self, destination) - if not self.caller.auth_account or self.caller.auth_account.class ~= 'sipaccount' then - self.log:error('VOICEMAIL - incompatible destination'); - return { continue = false, code = 404, phrase = 'Mailbox not found' } - end - + require 'common.str'; require 'dialplan.voicemail' - local voicemail_account = dialplan.voicemail.Voicemail:new{ log = self.log, database = self.database }:find_by_sip_account_id(self.caller.auth_account.id); + + local voicemail_account = nil; + + local sip_account_id + if not common.str.blank(destination.number) and false then + voicemail_account = dialplan.voicemail.Voicemail:new{ log = self.log, database = self.database }:find_by_number(destination.number); + elseif self.caller.auth_account and self.caller.auth_account.class == 'sipaccount' then + voicemail_account = dialplan.voicemail.Voicemail:new{ log = self.log, database = self.database }:find_by_sip_account_id(self.caller.auth_account.id); + end if not voicemail_account then self.log:error('VOICEMAIL - no mailbox'); diff --git a/misc/freeswitch/scripts/dialplan/voicemail.lua b/misc/freeswitch/scripts/dialplan/voicemail.lua index ae7d0a1..caeeb48 100644 --- a/misc/freeswitch/scripts/dialplan/voicemail.lua +++ b/misc/freeswitch/scripts/dialplan/voicemail.lua @@ -66,15 +66,14 @@ function Voicemail.find_by_name(self, account_name) return voicemail_account end --- Find Voicemail account by name +-- Find Voicemail account by number function Voicemail.find_by_number(self, phone_number) local sip_account = nil; require "common.phone_number" - local phone_number_class = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database }; - local destination_number_object = phone_number_class:find_by_number(phone_number); - if destination_number_object and destination_number_object.record.phone_numberable_type == "SipAccount" then - return Voicemail:find_by_sip_account_id(destination_number_object.record.phone_numberable_id); + local destination_number_object = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database }:find_by_number(phone_number); + if destination_number_object and destination_number_object.record.phone_numberable_type:lower() == "sipaccount" then + return self:find_by_sip_account_id(destination_number_object.record.phone_numberable_id); end return false; diff --git a/misc/freeswitch/scripts/event/perimeter_defense.lua b/misc/freeswitch/scripts/event/perimeter_defense.lua index acdfa8d..5bd124b 100644 --- a/misc/freeswitch/scripts/event/perimeter_defense.lua +++ b/misc/freeswitch/scripts/event/perimeter_defense.lua @@ -31,9 +31,10 @@ end function PerimeterDefense.event_handlers(self) return { CUSTOM = { - ['sofia::pre_register'] = self.sofia_pre_register, - ['sofia::register_attempt'] = self.sofia_register_attempt, - ['sofia::register_failure'] = self.sofia_register_failure, + ['sofia::pre_register'] = self.sofia_pre_register, + ['sofia::register_attempt'] = self.sofia_register_attempt, + ['sofia::register_failure'] = self.sofia_register_failure, + ['perimeter::control'] = self.perimeter_control, }, CHANNEL_HANGUP = { [true] = self.channel_hangup }, }; @@ -112,3 +113,20 @@ function PerimeterDefense.channel_hangup(self, event) local record = self:to_call_record(event, 'channel_hangup'); self.perimeter:check(record); end + + +function PerimeterDefense.control_to_action(self, event) + return { + key = event:getHeader('key'), + }; +end + + +function PerimeterDefense.perimeter_control(self, event) + local action = event:getHeader('action'); + if self.perimeter['action_' .. action] then + self.perimeter['action_' .. action](self.perimeter, self:control_to_action(event)) + else + self.log:error('[perimeter_defense] PERIMETER_DEFENSE - could not execute action: ', action); + end +end |