summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wintermeyer <stefan.wintermeyer@amooma.de>2013-02-12 13:53:28 +0100
committerStefan Wintermeyer <stefan.wintermeyer@amooma.de>2013-02-12 13:53:28 +0100
commitc9066760fd1f5f2f892ce2be5cf2a83bb5210246 (patch)
tree82ecdd528e803ccd1b469dc13482e06cf8ea0b8e
parent0b97717b2171820dea41de8df705f8f0e4b71464 (diff)
parentfb66a5e5a4c5d5f9eac4a5e8de6a286482cb55d5 (diff)
Release a new beta.5.1-beta4
-rw-r--r--Gemfile13
-rw-r--r--Gemfile.lock62
-rw-r--r--app/assets/javascripts/application.js1
-rw-r--r--app/assets/javascripts/call_route.js.coffee6
-rw-r--r--app/assets/javascripts/phone_number.js.coffee6
-rw-r--r--app/assets/javascripts/route_element.js.coffee6
-rw-r--r--app/assets/javascripts/softkey.js.coffee6
-rw-r--r--app/assets/stylesheets/application.css4
-rw-r--r--app/assets/stylesheets/call_routes.css.scss5
-rw-r--r--app/assets/stylesheets/phone_numbers.css.scss5
-rw-r--r--app/assets/stylesheets/route_elements.css.scss5
-rw-r--r--app/assets/stylesheets/softkeys.css.scss5
-rw-r--r--app/controllers/application_controller.rb63
-rw-r--r--app/controllers/backup_jobs_controller.rb46
-rw-r--r--app/controllers/call_forwards_controller.rb4
-rw-r--r--app/controllers/call_routes_controller.rb93
-rw-r--r--app/controllers/config_polycom_controller.rb69
-rw-r--r--app/controllers/config_siemens_controller.rb12
-rw-r--r--app/controllers/config_snom_controller.rb48
-rw-r--r--app/controllers/fax_documents_controller.rb25
-rw-r--r--app/controllers/gemeinschaft_setups_controller.rb7
-rw-r--r--app/controllers/gui_functions_controller.rb2
-rw-r--r--app/controllers/intruders_controller.rb41
-rw-r--r--app/controllers/page_controller.rb14
-rw-r--r--app/controllers/phone_numbers_controller.rb45
-rw-r--r--app/controllers/route_elements_controller.rb16
-rw-r--r--app/controllers/softkeys_controller.rb23
-rw-r--r--app/controllers/system_messages_controller.rb30
-rw-r--r--app/controllers/tenants_controller.rb9
-rw-r--r--app/helpers/backup_jobs_helper.rb2
-rw-r--r--app/helpers/intruders_helper.rb2
-rw-r--r--app/helpers/system_messages_helper.rb2
-rw-r--r--app/models/ability.rb12
-rw-r--r--app/models/backup_job.rb51
-rw-r--r--app/models/call.rb70
-rw-r--r--app/models/call_forward.rb2
-rw-r--r--app/models/call_route.rb8
-rw-r--r--app/models/gateway.rb6
-rw-r--r--app/models/gateway_setting.rb1
-rw-r--r--app/models/intruder.rb37
-rw-r--r--app/models/sip_account.rb2
-rw-r--r--app/models/softkey.rb32
-rw-r--r--app/models/system_message.rb7
-rw-r--r--app/uploaders/backup_file_uploader.rb55
-rw-r--r--app/views/backup_jobs/_form.html.haml7
-rw-r--r--app/views/backup_jobs/_form_core.html.haml5
-rw-r--r--app/views/backup_jobs/_index_core.html.haml49
-rw-r--r--app/views/backup_jobs/edit.html.haml3
-rw-r--r--app/views/backup_jobs/index.html.haml6
-rw-r--r--app/views/backup_jobs/new.html.haml3
-rw-r--r--app/views/backup_jobs/show.html.haml22
-rw-r--r--app/views/call_histories/_index_core.html.haml2
-rw-r--r--app/views/call_routes/_form_core.html.haml4
-rw-r--r--app/views/call_routes/_index_core.html.haml12
-rw-r--r--app/views/call_routes/index.html.haml11
-rw-r--r--app/views/call_routes/show.html.haml46
-rw-r--r--app/views/call_routes/show.xml.haml5
-rw-r--r--app/views/call_routes/show_variables.html.haml13
-rw-r--r--app/views/config_snom/show.xml.haml8
-rw-r--r--app/views/fax_accounts/_index_core.html.haml4
-rw-r--r--app/views/fax_accounts/show.html.haml6
-rw-r--r--app/views/gateways/show.xml.haml17
-rw-r--r--app/views/gemeinschaft_setups/new.de.html.haml1
-rw-r--r--app/views/gemeinschaft_setups/new.html.haml1
-rw-r--r--app/views/gs_nodes/sync.xml.haml2
-rw-r--r--app/views/gs_parameters/_index_core.html.haml14
-rw-r--r--app/views/gs_parameters/index.html.haml12
-rw-r--r--app/views/intruders/_form.html.haml7
-rw-r--r--app/views/intruders/_form_core.html.haml5
-rw-r--r--app/views/intruders/_index_core.html.haml37
-rw-r--r--app/views/intruders/edit.html.haml3
-rw-r--r--app/views/intruders/index.html.haml6
-rw-r--r--app/views/intruders/new.html.haml3
-rw-r--r--app/views/intruders/show.html.haml52
-rw-r--r--app/views/layouts/_footer.html.haml4
-rw-r--r--app/views/layouts/_navbar.html.haml13
-rw-r--r--app/views/phone_numbers/_form_core.html.haml4
-rw-r--r--app/views/phone_numbers/_index_core.html.haml9
-rw-r--r--app/views/phones/_form_core.html.haml2
-rw-r--r--app/views/phones/show.html.haml2
-rw-r--r--app/views/route_elements/_index_core.html.haml50
-rw-r--r--app/views/route_elements/show.html.haml51
-rw-r--r--app/views/shared/_index_view_edit_destroy_part.html.haml18
-rw-r--r--app/views/softkeys/_form_core.html.haml2
-rw-r--r--app/views/softkeys/_index_core.html.haml34
-rw-r--r--app/views/softkeys/show.html.haml4
-rw-r--r--app/views/system_messages/_form.html.haml7
-rw-r--r--app/views/system_messages/_form_core.html.haml2
-rw-r--r--app/views/system_messages/_index_core.html.haml12
-rw-r--r--app/views/system_messages/index.html.haml3
-rw-r--r--app/views/system_messages/new.html.haml3
-rw-r--r--app/views/system_messages/show.html.haml8
-rw-r--r--app/views/tenants/_admin_area.de.html.haml (renamed from app/views/tenants/_admin_area.html.haml)6
-rw-r--r--app/views/tenants/_admin_area.en.html.haml42
-rw-r--r--app/views/tenants/_table_of_backup_jobs.html.haml11
-rw-r--r--app/views/tenants/show.html.haml2
-rw-r--r--config/backup.rb60
-rw-r--r--config/locales/de.yml2
-rw-r--r--config/locales/navigation.de.yml3
-rw-r--r--config/locales/navigation.en.yml3
-rw-r--r--config/locales/views/backup_jobs/de.yml61
-rw-r--r--config/locales/views/backup_jobs/en.yml61
-rw-r--r--config/locales/views/call_routes/de.yml29
-rw-r--r--config/locales/views/call_routes/en.yml5
-rw-r--r--config/locales/views/gemeinschaft_setups/de.yml3
-rw-r--r--config/locales/views/gemeinschaft_setups/en.yml3
-rw-r--r--config/locales/views/intruders/de.yml110
-rw-r--r--config/locales/views/intruders/en.yml110
-rw-r--r--config/locales/views/phones/de.yml6
-rw-r--r--config/locales/views/route_elements/de.yml20
-rw-r--r--config/locales/views/sip_accounts/de.yml4
-rw-r--r--config/locales/views/system_messages/de.yml38
-rw-r--r--config/locales/views/system_messages/en.yml38
-rw-r--r--config/routes.rb116
-rw-r--r--config/schedule.rb24
-rw-r--r--db/migrate/20120127101726_create_system_messages.rb13
-rw-r--r--db/migrate/20130129154700_add_sso_key.rb9
-rw-r--r--db/migrate/20130130185300_add_no_copy_headers.rb9
-rw-r--r--db/migrate/20130202140927_add_trunk_access_code_to_gemeinschaft_setup.rb5
-rw-r--r--db/migrate/20130203164500_remove_perimeter_parameters.rb16
-rw-r--r--db/migrate/20130203165800_add_perimeter_parameters.rb23
-rw-r--r--db/migrate/20130203174300_start_perimeter_defense.rb10
-rw-r--r--db/migrate/20130204065900_split_perimeter_parameters.rb30
-rw-r--r--db/migrate/20130205102838_create_backup_jobs.rb16
-rw-r--r--db/migrate/20130205151844_add_queue_to_delayed_jobs.rb9
-rw-r--r--db/migrate/20130206144829_add_backup_file_to_backup_job.rb5
-rw-r--r--db/migrate/20130207082728_remove_size_of_the_backup_from_backup_job.rb9
-rw-r--r--db/migrate/20130208065700_add_softkeyable_to_softkey.rb16
-rw-r--r--db/migrate/20130210075617_create_intruders.rb28
-rw-r--r--db/migrate/20130212071000_default_profile_to_template.rb13
-rw-r--r--db/schema.rb46
-rw-r--r--lib/freeswitch_event.rb20
-rw-r--r--lib/tasks/backup.rake6
-rw-r--r--lib/tasks/csv_user_import.rake (renamed from lib/tasks/cvs_user_import.rake)0
-rw-r--r--lib/tasks/gs_cluster.rake8
-rw-r--r--misc/freeswitch/conf/freeswitch.xml466
-rw-r--r--misc/freeswitch/scripts/common/database.lua40
-rw-r--r--misc/freeswitch/scripts/common/fapi.lua5
-rw-r--r--misc/freeswitch/scripts/common/intruder.lua51
-rw-r--r--misc/freeswitch/scripts/common/perimeter.lua241
-rw-r--r--misc/freeswitch/scripts/common/sip_account.lua8
-rw-r--r--misc/freeswitch/scripts/common/str.lua17
-rw-r--r--misc/freeswitch/scripts/configuration.lua18
-rw-r--r--misc/freeswitch/scripts/dialplan/acd.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/dialplan.lua18
-rw-r--r--misc/freeswitch/scripts/dialplan/dtmf.lua69
-rw-r--r--misc/freeswitch/scripts/dialplan/functions.lua20
-rw-r--r--misc/freeswitch/scripts/dialplan/hunt_group.lua13
-rw-r--r--misc/freeswitch/scripts/dialplan/router.lua12
-rw-r--r--misc/freeswitch/scripts/dialplan/sip_call.lua71
-rw-r--r--misc/freeswitch/scripts/dialplan_default.lua37
-rw-r--r--misc/freeswitch/scripts/event/dump_variables.lua52
-rw-r--r--misc/freeswitch/scripts/event/event.lua33
-rw-r--r--misc/freeswitch/scripts/event/perimeter.lua107
-rw-r--r--misc/freeswitch/scripts/event/perimeter_defense.lua114
-rw-r--r--misc/freeswitch/scripts/event_manager.lua21
-rw-r--r--misc/freeswitch/scripts/fax_daemon.lua43
-rw-r--r--misc/freeswitch/scripts/http_request.lua2
-rw-r--r--misc/freeswitch/scripts/phones/phone.lua5
-rw-r--r--misc/freeswitch/scripts/send_fax.lua14
-rw-r--r--private_pub.ru8
-rw-r--r--test/functional/backup_jobs_controller_test.rb49
-rw-r--r--test/functional/intruders_controller_test.rb49
-rw-r--r--test/functional/system_messages_controller_test.rb49
-rw-r--r--test/unit/backup_job_test.rb7
-rw-r--r--test/unit/callthrough_test.rb12
-rw-r--r--test/unit/intruder_test.rb7
-rw-r--r--test/unit/system_message_test.rb7
168 files changed, 3325 insertions, 944 deletions
diff --git a/Gemfile b/Gemfile
index f0fd360..b390a28 100644
--- a/Gemfile
+++ b/Gemfile
@@ -58,13 +58,10 @@ gem "mini_magick"
# Pagination https://github.com/mislav/will_paginate/wiki/Installation
gem 'will_paginate'
-# DelayedJob
-gem 'delayed_job'
+# DelayedJob https://github.com/collectiveidea/delayed_job
+gem 'daemons'
gem 'delayed_job_active_record'
-# Private Pub http://railscasts.com/episodes/316-private-pub
-gem 'private_pub'
-
# https://github.com/iain/http_accept_language
gem 'http_accept_language'
@@ -79,6 +76,12 @@ gem 'unicorn'
gem 'thin'
+# Backup https://github.com/meskyanichi/backup
+gem 'backup'
+
+# Cronjobs
+gem 'whenever'
+
# Local Variables:
# mode: ruby
# End:
diff --git a/Gemfile.lock b/Gemfile.lock
index 33e77ff..8491109 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -29,12 +29,14 @@ GEM
i18n (~> 0.6)
multi_json (~> 1.0)
acts_as_list (0.1.9)
- addressable (2.3.2)
arel (3.0.2)
+ backup (3.0.27)
+ open4 (~> 1.3.0)
+ thor (>= 0.15.4, < 2)
bcrypt-ruby (3.0.1)
- better_errors (0.3.2)
+ better_errors (0.5.0)
coderay (>= 1.0.0)
- erubis (>= 2.7.0)
+ erubis (>= 2.6.6)
binding_of_caller (0.6.8)
breadcrumbs_on_rails (2.3.0)
builder (3.0.4)
@@ -44,6 +46,7 @@ GEM
carrierwave (0.8.0)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
+ chronic (0.9.0)
chunky_png (1.2.7)
coderay (1.0.8)
coffee-rails (3.2.2)
@@ -59,53 +62,34 @@ GEM
sass (~> 3.1)
compass-rails (1.0.3)
compass (>= 0.12.2, < 0.14)
- cookiejar (0.3.0)
daemons (1.1.9)
dalli (2.6.2)
- delayed_job (3.0.4)
+ delayed_job (3.0.5)
activesupport (~> 3.0)
- delayed_job_active_record (0.3.3)
+ delayed_job_active_record (0.4.0)
activerecord (>= 2.1.0, < 4)
delayed_job (~> 3.0)
- em-http-request (1.0.3)
- addressable (>= 2.2.3)
- cookiejar
- em-socksify
- eventmachine (>= 1.0.0.beta.4)
- http_parser.rb (>= 0.5.3)
- em-socksify (0.2.1)
- eventmachine (>= 1.0.0.beta.4)
erubis (2.7.0)
eventmachine (1.0.0)
execjs (1.4.0)
multi_json (~> 1.0)
factory_girl (4.2.0)
activesupport (>= 3.0.0)
- factory_girl_rails (4.2.0)
+ factory_girl_rails (4.2.1)
factory_girl (~> 4.2.0)
railties (>= 3.0.0)
- faye (0.8.8)
- cookiejar (>= 0.3.0)
- em-http-request (>= 0.3.0)
- eventmachine (>= 0.12.0)
- faye-websocket (>= 0.4.0)
- rack (>= 1.0.0)
- yajl-ruby (>= 1.0.0)
- faye-websocket (0.4.6)
- eventmachine (>= 0.12.0)
fssm (0.2.10)
haml (3.1.7)
hike (1.2.1)
hirb (0.7.1)
http_accept_language (1.0.2)
- http_parser.rb (0.5.3)
i18n (0.6.1)
inifile (2.0.2)
journey (1.0.4)
- jquery-rails (2.2.0)
+ jquery-rails (2.2.1)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
- json (1.7.6)
+ json (1.7.7)
kgio (2.8.0)
macaddr (1.6.1)
systemu (~> 2.5.0)
@@ -113,21 +97,20 @@ GEM
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
- mime-types (1.19)
+ mime-types (1.21)
mini_magick (3.4)
subexec (~> 0.2.1)
- multi_json (1.5.0)
+ multi_json (1.5.1)
mysql2 (0.3.11)
nokogiri (1.5.6)
+ open4 (1.3.0)
polyglot (0.3.3)
- private_pub (1.0.3)
- faye
quiet_assets (1.0.1)
railties (~> 3.1)
- rack (1.4.4)
+ rack (1.4.5)
rack-cache (1.2)
rack (>= 0.4)
- rack-ssl (1.3.2)
+ rack-ssl (1.3.3)
rack
rack-test (0.6.2)
rack (>= 1.0)
@@ -148,7 +131,7 @@ GEM
thor (>= 0.14.6, < 2.0)
raindrops (0.10.0)
rake (10.0.3)
- rdoc (3.12)
+ rdoc (3.12.1)
json (~> 1.4)
sass (3.2.5)
sass-rails (3.2.6)
@@ -187,20 +170,23 @@ GEM
uglifier (1.3.0)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
- unicorn (4.5.0)
+ unicorn (4.6.0)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
uuid (2.3.6)
macaddr (~> 1.0)
+ whenever (0.8.2)
+ activesupport (>= 2.3.4)
+ chronic (>= 0.6.3)
will_paginate (3.0.4)
- yajl-ruby (1.1.0)
PLATFORMS
ruby
DEPENDENCIES
acts_as_list
+ backup
bcrypt-ruby
better_errors
binding_of_caller
@@ -210,8 +196,8 @@ DEPENDENCIES
carrierwave
coffee-rails (~> 3.2.1)
compass-rails
+ daemons
dalli
- delayed_job
delayed_job_active_record
factory_girl
factory_girl_rails
@@ -224,7 +210,6 @@ DEPENDENCIES
mini_magick
mysql2
nokogiri
- private_pub
quiet_assets
rails (= 3.2.11)
sass-rails
@@ -237,4 +222,5 @@ DEPENDENCIES
uglifier (>= 1.3.0)
unicorn
uuid
+ whenever
will_paginate
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 9097d83..c6f4107 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -11,5 +11,6 @@
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
+//= require jquery-ui
//= require jquery_ujs
//= require_tree .
diff --git a/app/assets/javascripts/call_route.js.coffee b/app/assets/javascripts/call_route.js.coffee
new file mode 100644
index 0000000..fab7f10
--- /dev/null
+++ b/app/assets/javascripts/call_route.js.coffee
@@ -0,0 +1,6 @@
+jQuery ->
+ $('.call_routes').sortable
+ axis: 'y'
+ handle: '.handle'
+ update: ->
+ $.post($(this).data('update-url'), $(this).sortable('serialize')) \ No newline at end of file
diff --git a/app/assets/javascripts/phone_number.js.coffee b/app/assets/javascripts/phone_number.js.coffee
new file mode 100644
index 0000000..ee983ee
--- /dev/null
+++ b/app/assets/javascripts/phone_number.js.coffee
@@ -0,0 +1,6 @@
+jQuery ->
+ $('#phone_numbers').sortable
+ axis: 'y'
+ handle: '.handle'
+ update: ->
+ $.post($(this).data('update-url'), $(this).sortable('serialize')) \ No newline at end of file
diff --git a/app/assets/javascripts/route_element.js.coffee b/app/assets/javascripts/route_element.js.coffee
new file mode 100644
index 0000000..75dc553
--- /dev/null
+++ b/app/assets/javascripts/route_element.js.coffee
@@ -0,0 +1,6 @@
+jQuery ->
+ $('#route_elements').sortable
+ axis: 'y'
+ handle: '.handle'
+ update: ->
+ $.post($(this).data('update-url'), $(this).sortable('serialize')) \ No newline at end of file
diff --git a/app/assets/javascripts/softkey.js.coffee b/app/assets/javascripts/softkey.js.coffee
new file mode 100644
index 0000000..a8d2d0c
--- /dev/null
+++ b/app/assets/javascripts/softkey.js.coffee
@@ -0,0 +1,6 @@
+jQuery ->
+ $('#softkeys').sortable
+ axis: 'y'
+ handle: '.handle'
+ update: ->
+ $.post($(this).data('update-url'), $(this).sortable('serialize')) \ No newline at end of file
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 9093f8e..44868e4 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -12,4 +12,8 @@
*= require bootstrap/bootstrap
*= require bootstrap/bootstrap-responsive
*= require gemeinschaft-generic
+ *= require call_routes
+ *= require softkeys
+ *= require phone_numbers
+ *= require route_elements
*/
diff --git a/app/assets/stylesheets/call_routes.css.scss b/app/assets/stylesheets/call_routes.css.scss
new file mode 100644
index 0000000..d39e1d1
--- /dev/null
+++ b/app/assets/stylesheets/call_routes.css.scss
@@ -0,0 +1,5 @@
+.call_routes .handle {
+ font-size: 12px;
+ color: #777;
+ cursor: move;
+} \ No newline at end of file
diff --git a/app/assets/stylesheets/phone_numbers.css.scss b/app/assets/stylesheets/phone_numbers.css.scss
new file mode 100644
index 0000000..141a1f7
--- /dev/null
+++ b/app/assets/stylesheets/phone_numbers.css.scss
@@ -0,0 +1,5 @@
+#phone_numbers .handle {
+ font-size: 12px;
+ color: #777;
+ cursor: move;
+} \ No newline at end of file
diff --git a/app/assets/stylesheets/route_elements.css.scss b/app/assets/stylesheets/route_elements.css.scss
new file mode 100644
index 0000000..a0080ab
--- /dev/null
+++ b/app/assets/stylesheets/route_elements.css.scss
@@ -0,0 +1,5 @@
+#route_elements .handle {
+ font-size: 12px;
+ color: #777;
+ cursor: move;
+} \ No newline at end of file
diff --git a/app/assets/stylesheets/softkeys.css.scss b/app/assets/stylesheets/softkeys.css.scss
new file mode 100644
index 0000000..425c6f1
--- /dev/null
+++ b/app/assets/stylesheets/softkeys.css.scss
@@ -0,0 +1,5 @@
+#softkeys .handle {
+ font-size: 12px;
+ color: #777;
+ cursor: move;
+} \ No newline at end of file
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index e4165f3..d1d918e 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -2,26 +2,21 @@ class ApplicationController < ActionController::Base
protect_from_forgery
- before_filter :set_locale
+ before_filter :start_setup_if_new_installation
- before_filter :go_to_setup_if_new_installation
- before_filter :home_breadcrumb
-
+ before_filter :set_locale
helper_method :current_user
-
+
helper_method :guess_local_ip_address
helper_method :guess_local_host
-
+
+ before_filter :home_breadcrumb
+
helper_method :'have_https?'
+ helper_method :'single_sign_on_system?'
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)
@@ -56,6 +51,8 @@ class ApplicationController < ActionController::Base
def random_pin
if GsParameter.get('MINIMUM_PIN_LENGTH') > 0
(1..GsParameter.get('MINIMUM_PIN_LENGTH')).map{|i| (0 .. 9).to_a.sample}.join
+ else
+ (1..8).map{|i| (0 .. 9).to_a.sample}.join
end
end
@@ -106,33 +103,41 @@ class ApplicationController < ActionController::Base
end
rescue_from CanCan::AccessDenied do |exception|
- if @current_user
+ 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
+ # You need to login first.
+ redirect_to log_in_path, :alert => 'Access denied! You need to login first.'
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
+ def current_user
+ if session[:user_id].nil? && single_sign_on_system?
+ auth_user = User.where(:user_name => request.env[GsParameter.get('SingleSignOnEnvUserNameKey')]).first
+ else
+ if session[:user_id] && User.where(:id => session[:user_id]).any?
+ auth_user = User.where(:id => session[:user_id]).first
+ else
+ auth_user = nil
+ end
+ end
+ session[:user_id] = auth_user.try(:id)
+ return auth_user
+ end
+
+ def single_sign_on_system?
+ if GsParameter.get('SingleSignOnEnvUserNameKey').blank?
+ false
+ else
+ true
end
- @current_user
- end
+ end
- def go_to_setup_if_new_installation
+ def start_setup_if_new_installation
if Rails.env != 'test'
- if GemeinschaftSetup.all.count == 0
+ if GemeinschaftSetup.count == 0
redirect_to new_gemeinschaft_setup_path
end
end
diff --git a/app/controllers/backup_jobs_controller.rb b/app/controllers/backup_jobs_controller.rb
new file mode 100644
index 0000000..31b9c21
--- /dev/null
+++ b/app/controllers/backup_jobs_controller.rb
@@ -0,0 +1,46 @@
+class BackupJobsController < ApplicationController
+ load_and_authorize_resource :backup_job
+
+ before_filter :spread_breadcrumbs
+
+ def index
+ end
+
+ def show
+ end
+
+ def new
+ # Do the same as create.
+ #
+ @backup_job = BackupJob.new(:started_at => Time.now)
+
+ if @backup_job.save
+ redirect_to backup_jobs_path, :notice => t('backup_jobs.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def create
+ @backup_job = BackupJob.new(:started_at => Time.now)
+
+ if @backup_job.save
+ redirect_to backup_jobs_path, :notice => t('backup_jobs.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def destroy
+ @backup_job.destroy
+ redirect_to backup_jobs_url, :notice => t('backup_jobs.controller.successfuly_destroyed')
+ end
+
+ private
+ def spread_breadcrumbs
+ add_breadcrumb t("backup_jobs.index.page_title"), backup_jobs_path
+ if @backup_job && !@backup_job.new_record?
+ add_breadcrumb @backup_job, @backup_job
+ end
+ end
+end
diff --git a/app/controllers/call_forwards_controller.rb b/app/controllers/call_forwards_controller.rb
index 001ed60..b1ced87 100644
--- a/app/controllers/call_forwards_controller.rb
+++ b/app/controllers/call_forwards_controller.rb
@@ -28,7 +28,7 @@ class CallForwardsController < ApplicationController
@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)
+ 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
@@ -112,7 +112,7 @@ class CallForwardsController < ApplicationController
voice_mail_destination,
]
- if GuiFunction.display?('huntgroup_in_destination_field_in_call_forward_form', @current_user)
+ 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"
diff --git a/app/controllers/call_routes_controller.rb b/app/controllers/call_routes_controller.rb
index 0259a10..2dcd648 100644
--- a/app/controllers/call_routes_controller.rb
+++ b/app/controllers/call_routes_controller.rb
@@ -1,5 +1,11 @@
class CallRoutesController < ApplicationController
- authorize_resource :call_route
+ authorize_resource :call_route, :except => [:sort]
+
+ before_filter { |controller|
+ if !params[:call_route].blank? && !params[:call_route][:endpoint_str].blank?
+ params[:call_route][:endpoint_type], delimeter, params[:call_route][:endpoint_id] = params[:call_route][:endpoint_str].partition('=')
+ end
+ }
def index
@call_routes = CallRoute.order([:routing_table, :position])
@@ -14,6 +20,11 @@ class CallRoutesController < ApplicationController
def new
@call_route = CallRoute.new
+ @endpoints = Gateway.all.collect {|r| [ "gateway: #{r.to_s}", "gateway=#{r.id}" ] }
+ @endpoints << [ 'phonenumber', 'phonenumber=' ]
+ @endpoints << [ 'dialplanfunction', 'dialplanfunction=' ]
+ @endpoints << [ 'hangup', 'hangup=' ]
+ @endpoints << [ 'unknown', 'unknown=' ]
spread_breadcrumbs
end
@@ -29,12 +40,18 @@ class CallRoutesController < ApplicationController
def edit
@call_route = CallRoute.find(params[:id])
+ @endpoints = Gateway.all.collect {|r| [ "gateway: #{r.to_s}", "gateway=#{r.id}" ] }
+ @endpoints << [ 'phonenumber', 'phonenumber=' ]
+ @endpoints << [ 'dialplanfunction', 'dialplanfunction=' ]
+ @endpoints << [ 'hangup', 'hangup=' ]
+ @endpoints << [ 'unknown', 'unknown=' ]
spread_breadcrumbs
end
def update
@call_route = CallRoute.find(params[:id])
spread_breadcrumbs
+
if @call_route.update_attributes(call_route_parameter_params)
redirect_to @call_route, :notice => t('call_routes.controller.successfuly_updated')
else
@@ -48,21 +65,31 @@ class CallRoutesController < ApplicationController
redirect_to call_routes_url, :notice => t('call_routes.controller.successfuly_destroyed')
end
- def move_higher
- @call_route = CallRoute.find(params[:id])
- @call_route.move_higher
- redirect_to :back
+ def sort
+ params[:call_route].each_with_index do |id, index|
+ CallRoute.update_all({position: index+1}, {id: id})
+ #CallRoute.find(:id).move_to_bottom
+ end
+ render nothing: true
end
- def move_lower
- @call_route = CallRoute.find(params[:id])
- @call_route.move_lower
- redirect_to :back
+ def show_variables
+ @channel_variables = Hash.new()
+ file_name = '/var/log/freeswitch/variables'
+ if File.readable?(file_name)
+ File.readlines(file_name).each do |line|
+ key, delimeter, value = line.partition(': ')
+ key = to_channel_variable_name(key)
+ if !key.blank?
+ @channel_variables[key] = URI.unescape(value.gsub(/\n/, ''));
+ end
+ end
+ end
end
private
def call_route_parameter_params
- params.require(:call_route).permit(:routing_table, :name, :endpoint_type, :endpoint_id)
+ params.require(:call_route).permit(:routing_table, :name, :endpoint_type, :endpoint_id, :position)
end
def spread_breadcrumbs
@@ -72,4 +99,50 @@ class CallRoutesController < ApplicationController
end
end
+ def to_channel_variable_name(name)
+ variables_map = {
+ 'Channel-State' => 'state',
+ 'Channel-State-Number' => 'state_number',
+ 'Channel-Name' => 'channel_name',
+ 'Unique-ID' => 'uuid',
+ 'Call-Direction' => 'direction',
+ 'Answer-State' => 'state',
+ 'Channel-Read-Codec-Name' => 'read_codec',
+ 'Channel-Read-Codec-Rate' => 'read_rate',
+ 'Channel-Write-Codec-Name' => 'write_codec',
+ 'Channel-Write-Codec-Rate' => 'write_rate',
+ 'Caller-Username' => 'username',
+ 'Caller-Dialplan' => 'dialplan',
+ 'Caller-Caller-ID-Name' => 'caller_id_name',
+ 'Caller-Caller-ID-Number' => 'caller_id_number',
+ 'Caller-ANI' => 'ani',
+ 'Caller-ANI-II' => 'aniii',
+ 'Caller-Network-Addr' => 'network_addr',
+ 'Caller-Destination-Number' => 'destination_number',
+ 'Caller-Unique-ID' => 'uuid',
+ 'Caller-Source' => 'source',
+ 'Caller-Context' => 'context',
+ 'Caller-RDNIS' => 'rdnis',
+ 'Caller-Channel-Name' => 'channel_name',
+ 'Caller-Profile-Index' => 'profile_index',
+ 'Caller-Channel-Created-Time' => 'created_time',
+ 'Caller-Channel-Answered-Time' => 'answered_time',
+ 'Caller-Channel-Hangup-Time' => 'hangup_time',
+ 'Caller-Channel-Transfer-Time' => 'transfer_time',
+ 'Caller-Screen-Bit' => 'screen_bit',
+ 'Caller-Privacy-Hide-Name' => 'privacy_hide_name',
+ 'Caller-Privacy-Hide-Number' => 'privacy_hide_number',
+ }
+
+ name = name.gsub(/[^a-zA-Z1-9_\-]/, '')
+
+ if variables_map[name]
+ return variables_map[name]
+ elsif name.match(/^variable_/)
+ return name.gsub(/^variable_/, '')
+ end
+
+ return nil
+ end
+
end
diff --git a/app/controllers/config_polycom_controller.rb b/app/controllers/config_polycom_controller.rb
index 9d44e51..fd730e3 100644
--- a/app/controllers/config_polycom_controller.rb
+++ b/app/controllers/config_polycom_controller.rb
@@ -26,12 +26,15 @@ class ConfigPolycomController < ApplicationController
if ! params[:sip_account].blank?
@sip_account = @phone.sip_accounts.where({ :id => params[:sip_account].to_i }).first
+ if ! @sip_account && @phone.fallback_sip_account && @phone.fallback_sip_account.id == params[:sip_account].to_i
+ @sip_account = @phone.fallback_sip_account
+ end
if ! @sip_account
render(
:status => 404,
:layout => false,
:content_type => 'text/plain',
- :text => "<!-- SipAccount not found -->",
+ :text => "<!-- SipAccount ID:#{params[:sip_account]} not found -->",
)
return false
end
@@ -113,37 +116,41 @@ class ConfigPolycomController < ApplicationController
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
+ phone_sip_accounts = Array.new()
+ if @phone.sip_accounts && @phone.sip_accounts.count > 0
+ phone_sip_accounts = @phone.sip_accounts
+ elsif @phone.fallback_sip_account
+ phone_sip_accounts.push( @phone.fallback_sip_account )
+ end
+ sip_account_index = 0
+ phone_sip_accounts.each do |sip_account|
+ 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
+ @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
diff --git a/app/controllers/config_siemens_controller.rb b/app/controllers/config_siemens_controller.rb
index b7fa107..bbeba46 100644
--- a/app/controllers/config_siemens_controller.rb
+++ b/app/controllers/config_siemens_controller.rb
@@ -610,15 +610,21 @@ class ConfigSiemensController < ApplicationController
@new_settings << ['stimulus-led-control-uri', key_idx, '' ]
@new_settings << ['stimulus-DTMF-sequence', key_idx, '' ]
when 'call_forwarding'
+ if sk.softkeyable.class == CallForward then
@new_settings << ['function-key-def', key_idx, '63']
- @new_settings << ['stimulus-led-control-uri', key_idx, "f-cftg-#{sk.call_forward_id}" ]
+ @new_settings << ['stimulus-led-control-uri', key_idx, "f-cftg-#{sk.softkeyable.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-query', key_idx, "id=#{sk.softkeyable.id}&function=toggle"]
@new_settings << ['send-url-method', key_idx, '0']
@new_settings << ['blf-popup', key_idx, 'false']
+ else
+ @new_settings << ['function-key-def', key_idx, '0']
+ @new_settings << ['stimulus-led-control-uri', key_idx, '' ]
+ @new_settings << ['stimulus-DTMF-sequence', key_idx, '' ]
+ end
when 'call_forwarding_always'
phone_number = PhoneNumber.where(:number => sk.number, :phone_numberable_type => 'SipAccount').first
if phone_number
@@ -887,7 +893,7 @@ class ConfigSiemensController < ApplicationController
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
+ if !call_forwarding and @sip_account.softkeys.where(:softkeyable_id => @call_forwarding_id, :softkeyable_type => 'CallForward').count > 0
call_forwarding = CallForward.where(:id => @call_forwarding_id).first
end
diff --git a/app/controllers/config_snom_controller.rb b/app/controllers/config_snom_controller.rb
index e797a43..58cced2 100644
--- a/app/controllers/config_snom_controller.rb
+++ b/app/controllers/config_snom_controller.rb
@@ -247,6 +247,7 @@ class ConfigSnomController < ApplicationController
elsif @phone.fallback_sip_account
phone_sip_accounts.push( @phone.fallback_sip_account )
end
+ expiry_seconds = GsParameter.get('SIP_EXPIRY_SECONDS')
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 = {
@@ -259,7 +260,8 @@ class ConfigSnomController < ApplicationController
:name => sip_account.auth_name,
:realname => 'Call',
:idle_text => sip_account.caller_name,
- :mailbox => "<sip:#{sip_account.auth_name}@#{sip_account.host}>"
+ :mailbox => "<sip:#{sip_account.auth_name}@#{sip_account.host}>",
+ :expiry => expiry_seconds,
}
@sip_accounts.push(snom_sip_account)
sip_account_index = @sip_accounts.length
@@ -280,23 +282,47 @@ class ConfigSnomController < ApplicationController
@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'
+ when 'call_parking'
@softkeys.push({
:context => sip_account_index,
- :function => softkey.function,
+ :function => softkey.softkey_function.name,
: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}",
+ :to => "park+#{@softkeys.softkeyable_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",
+ :type => :dial,
+ :target => "f-tpark-#{@softkeys.softkeyable_id}",
+ :when => 'on press',
+ :states => 'connected,holding',
+ },{
+ :type => :dial,
+ :target => "f-park-#{@softkeys.softkeyable_id}",
:when => 'on press',
}],
})
+ when 'call_forwarding'
+ if softkey.softkeyable.class == CallForward then
+ @softkeys.push({
+ :context => sip_account_index,
+ :function => softkey.softkey_function.name,
+ :label => softkey.label,
+ :softkey => softkey,
+ :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
+ :subscription => {
+ :to => "f-cftg-#{softkey.softkeyable_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.softkeyable_id}&function=toggle",
+ :when => 'on press',
+ }],
+ })
+ end
when 'call_forwarding_always'
phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first
if phone_number
@@ -308,7 +334,7 @@ class ConfigSnomController < ApplicationController
@softkeys.push({
:context => sip_account_index,
- :function => softkey.function,
+ :function => softkey.softkey_function.name,
:label => softkey.label,
:softkey => softkey,
:general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
@@ -333,7 +359,7 @@ class ConfigSnomController < ApplicationController
@softkeys.push({
:context => sip_account_index,
- :function => softkey.function,
+ :function => softkey.softkey_function.name,
:label => softkey.label,
:softkey => softkey,
:general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
@@ -373,7 +399,7 @@ class ConfigSnomController < ApplicationController
if hunt_group_member
@softkeys.push({
:context => sip_account_index,
- :function => softkey.function,
+ :function => softkey.softkey_function.name,
:label => softkey.label,
:softkey => softkey,
:general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
@@ -403,7 +429,7 @@ class ConfigSnomController < ApplicationController
if acd_agent
@softkeys.push({
:context => sip_account_index,
- :function => softkey.function,
+ :function => softkey.softkey_function.name,
:label => softkey.label,
:softkey => softkey,
:general_type => t("softkeys.functions.#{softkey.softkey_function.name}"),
@@ -922,7 +948,7 @@ AAAA'
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
+ if !call_forwarding and @sip_account.softkeys.where(:softkeyable_id => @call_forwarding_id, :softkeyable_type => 'CallForward').count > 0
call_forwarding = CallForward.where(:id => @call_forwarding_id).first
end
diff --git a/app/controllers/fax_documents_controller.rb b/app/controllers/fax_documents_controller.rb
index eff9604..5653683 100644
--- a/app/controllers/fax_documents_controller.rb
+++ b/app/controllers/fax_documents_controller.rb
@@ -58,23 +58,18 @@ class FaxDocumentsController < ApplicationController
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)],
- ]
+ if @fax_account && @fax_account.fax_accountable.class == User
+ add_breadcrumb t("users.index.page_title"), tenant_users_path(@fax_account.fax_accountable.current_tenant)
+ add_breadcrumb @fax_account.fax_accountable, tenant_user_path(@fax_account.fax_accountable.current_tenant, @fax_account.fax_accountable)
end
- if !breadcrumbs.blank?
- breadcrumbs.each do |breadcrumb|
- add_breadcrumb breadcrumb[0], breadcrumb[1]
+
+ if @fax_account
+ add_breadcrumb t("fax_accounts.index.page_title"), user_fax_accounts_path(@fax_account.fax_accountable)
+ add_breadcrumb @fax_account, user_fax_account_path(@fax_account.fax_accountable, @fax_account)
+ if @fax_document && !@fax_document.new_record?
+ add_breadcrumb @fax_document, fax_account_fax_document_path(@fax_account, @fax_document)
end
end
end
diff --git a/app/controllers/gemeinschaft_setups_controller.rb b/app/controllers/gemeinschaft_setups_controller.rb
index 4f4a72a..a62df99 100644
--- a/app/controllers/gemeinschaft_setups_controller.rb
+++ b/app/controllers/gemeinschaft_setups_controller.rb
@@ -4,9 +4,9 @@ class GemeinschaftSetupsController < ApplicationController
#
caches_page :new, :gzip => :best_compression
- load_and_authorize_resource :gemeinschaft_setup
+ skip_before_filter :start_setup_if_new_installation
- skip_before_filter :go_to_setup_if_new_installation
+ load_and_authorize_resource :gemeinschaft_setup
def new
@user = @gemeinschaft_setup.build_user(
@@ -23,6 +23,7 @@ class GemeinschaftSetupsController < ApplicationController
@gemeinschaft_setup.default_company_name = generate_a_new_name(Tenant.new)
@gemeinschaft_setup.default_system_email = 'admin@localhost'
+ @gemeinschaft_setup.trunk_access_code = '0'
end
def create
@@ -52,7 +53,7 @@ class GemeinschaftSetupsController < ApplicationController
CallRoute.factory_defaults_prerouting(@gemeinschaft_setup.country.country_code,
@gemeinschaft_setup.country.trunk_prefix,
@gemeinschaft_setup.country.international_call_prefix,
- '',
+ @gemeinschaft_setup.trunk_access_code,
@gemeinschaft_setup.default_area_code
)
diff --git a/app/controllers/gui_functions_controller.rb b/app/controllers/gui_functions_controller.rb
index 0cb7898..4b57322 100644
--- a/app/controllers/gui_functions_controller.rb
+++ b/app/controllers/gui_functions_controller.rb
@@ -58,7 +58,7 @@ class GuiFunctionsController < ApplicationController
private
def load_user_groups
- @user_groups = Tenant.find(@current_user.current_tenant).user_groups.order(:position)
+ @user_groups = Tenant.find(current_user.current_tenant).user_groups.order(:position)
end
def spread_breadcrumbs
diff --git a/app/controllers/intruders_controller.rb b/app/controllers/intruders_controller.rb
new file mode 100644
index 0000000..eb34f2b
--- /dev/null
+++ b/app/controllers/intruders_controller.rb
@@ -0,0 +1,41 @@
+class IntrudersController < ApplicationController
+ def index
+ @intruders = Intruder.all
+ end
+
+ def show
+ @intruder = Intruder.find(params[:id])
+ end
+
+ def new
+ @intruder = Intruder.new
+ end
+
+ def create
+ @intruder = Intruder.new(params[:intruder])
+ if @intruder.save
+ redirect_to @intruder, :notice => t('intruders.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def edit
+ @intruder = Intruder.find(params[:id])
+ end
+
+ def update
+ @intruder = Intruder.find(params[:id])
+ if @intruder.update_attributes(params[:intruder])
+ redirect_to @intruder, :notice => t('intruders.controller.successfuly_updated')
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ @intruder = Intruder.find(params[:id])
+ @intruder.destroy
+ redirect_to intruders_url, :notice => t('intruders.controller.successfuly_destroyed')
+ end
+end
diff --git a/app/controllers/page_controller.rb b/app/controllers/page_controller.rb
index 8f4fa88..ed48e3c 100644
--- a/app/controllers/page_controller.rb
+++ b/app/controllers/page_controller.rb
@@ -2,7 +2,6 @@ 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
@@ -14,18 +13,5 @@ class PageController < ApplicationController
def help
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_numbers_controller.rb b/app/controllers/phone_numbers_controller.rb
index c562954..67c4922 100644
--- a/app/controllers/phone_numbers_controller.rb
+++ b/app/controllers/phone_numbers_controller.rb
@@ -1,22 +1,22 @@
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,
+ load_resource :phone_book_entry, :except => [:sort]
+ load_resource :sip_account, :except => [:sort]
+ load_resource :conference, :except => [:sort]
+ load_resource :fax_account, :except => [:sort]
+ load_resource :phone_number_range, :except => [:sort]
+ load_resource :callthrough, :except => [:sort]
+ load_resource :whitelist, :except => [:sort]
+ load_resource :access_authorization, :except => [:sort]
+ load_resource :hunt_group, :except => [:sort]
+ load_resource :hunt_group_member, :except => [:sort]
+ load_resource :automatic_call_distributor, :except => [:sort]
+ load_and_authorize_resource :phone_number, :except => [:sort], :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
+ before_filter :set_and_authorize_parent, :except => [:sort]
+ before_filter :spread_breadcrumbs, :except => [:sort]
def index
end
@@ -67,16 +67,6 @@ class PhoneNumbersController < ApplicationController
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
-
def call
sip_account = nil
current_user.sip_accounts.each do |user_sip_account|
@@ -94,6 +84,13 @@ class PhoneNumbersController < ApplicationController
redirect_to(:back)
end
+ def sort
+ params[:phone_number].each_with_index do |id, index|
+ PhoneNumber.update_all({position: index+1}, {id: id})
+ end
+ render nothing: true
+ end
+
private
def set_and_authorize_parent
@parent = @phone_book_entry || @sip_account || @conference || @fax_account ||
diff --git a/app/controllers/route_elements_controller.rb b/app/controllers/route_elements_controller.rb
index c4e4c1a..9c9033e 100644
--- a/app/controllers/route_elements_controller.rb
+++ b/app/controllers/route_elements_controller.rb
@@ -5,7 +5,7 @@ class RouteElementsController < ApplicationController
before_filter :spread_breadcrumbs
def index
- @route_elements = @call_route.route_elements
+ @route_elements = @call_route.route_elements.order([:position])
end
def show
@@ -44,14 +44,14 @@ class RouteElementsController < ApplicationController
redirect_to call_route_route_elements_path(@call_route), :notice => t('route_elements.controller.successfuly_destroyed')
end
- def move_higher
- @route_element.move_higher
- redirect_to :back
- end
+ def sort
+ #call_route = RouteElement.find(params[:route_element].first).call_route
+
+ params[:route_element].each do |route_element_id|
+ @call_route.route_elements.find(route_element_id).move_to_bottom
+ end
- def move_lower
- @route_element.move_lower
- redirect_to :back
+ render nothing: true
end
private
diff --git a/app/controllers/softkeys_controller.rb b/app/controllers/softkeys_controller.rb
index d2a2bb9..c9e8c20 100644
--- a/app/controllers/softkeys_controller.rb
+++ b/app/controllers/softkeys_controller.rb
@@ -1,9 +1,9 @@
class SoftkeysController < ApplicationController
- load_and_authorize_resource :sip_account
- load_and_authorize_resource :softkey, :through => [:sip_account]
+ load_and_authorize_resource :sip_account, :except => [:sort]
+ load_and_authorize_resource :softkey, :through => [:sip_account], :except => [:sort]
before_filter :set_available_call_forwards_and_softkey_functions, :only => [ :new, :edit, :update ]
- before_filter :spread_breadcrumbs
+ before_filter :spread_breadcrumbs, :except => [:sort]
def index
end
@@ -44,16 +44,17 @@ class SoftkeysController < ApplicationController
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 sort
+ sip_account = Softkey.find(params[:softkey].first).sip_account
+
+ params[:softkey].each do |softkey_id|
+ sip_account.softkeys.find(softkey_id).move_to_bottom
+ end
- def move_lower
- @softkey.move_lower
- redirect_to :back
+ render nothing: true
end
+
private
def set_available_call_forwards_and_softkey_functions
@@ -61,7 +62,7 @@ class SoftkeysController < ApplicationController
@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)
+ if GuiFunction.display?("softkey_function_#{softkey_function.name.downcase}_field_in_softkey_form", current_user)
@softkey_functions << softkey_function
end
end
diff --git a/app/controllers/system_messages_controller.rb b/app/controllers/system_messages_controller.rb
deleted file mode 100644
index d7fe515..0000000
--- a/app/controllers/system_messages_controller.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-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
index 37874b2..b6a96b7 100644
--- a/app/controllers/tenants_controller.rb
+++ b/app/controllers/tenants_controller.rb
@@ -8,6 +8,7 @@ class TenantsController < ApplicationController
def show
@tenant = Tenant.find(params[:id])
@gateways = Gateway.order(:updated_at)
+ @backup_jobs = BackupJob.order(:finished_at).last(5)
end
def new
@@ -27,17 +28,17 @@ class TenantsController < ApplicationController
if @tenant.save
# Become a member of this tenant.
#
- @tenant.tenant_memberships.create(:user_id => @current_user.id)
+ @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
+ 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
+ user_group.users << current_user
- @current_user.update_attributes!(:current_tenant_id => @tenant.id)
+ current_user.update_attributes!(:current_tenant_id => @tenant.id)
# Generate the internal_extensions
#
diff --git a/app/helpers/backup_jobs_helper.rb b/app/helpers/backup_jobs_helper.rb
new file mode 100644
index 0000000..06d8b9b
--- /dev/null
+++ b/app/helpers/backup_jobs_helper.rb
@@ -0,0 +1,2 @@
+module BackupJobsHelper
+end
diff --git a/app/helpers/intruders_helper.rb b/app/helpers/intruders_helper.rb
new file mode 100644
index 0000000..7243cf3
--- /dev/null
+++ b/app/helpers/intruders_helper.rb
@@ -0,0 +1,2 @@
+module IntrudersHelper
+end
diff --git a/app/helpers/system_messages_helper.rb b/app/helpers/system_messages_helper.rb
deleted file mode 100644
index fef2386..0000000
--- a/app/helpers/system_messages_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module SystemMessagesHelper
-end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 0d13dab..4c0844c 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -56,14 +56,14 @@ class Ability
can :read, PhoneBookEntry, :phone_book => { :id => user_group.phone_book_ids }
end
- # SystemMessages
- #
- cannot [:destroy, :edit, :update], SystemMessage
-
# A FacDocument can't be changed
#
cannot [:edit, :update], FaxDocument
+ # Backups can't be edited
+ #
+ cannot [:edit, :update], BackupJob
+
# Can manage GsNodes
#
can :manage, GsNode
@@ -156,10 +156,6 @@ class Ability
#
can :manage, CallForward, :phone_number_id => user.phone_number_ids
- # SystemMessages
- #
- can :read, SystemMessage, :user_id => user.id
-
# SoftkeyFunctions
#
can :read, SoftkeyFunction
diff --git a/app/models/backup_job.rb b/app/models/backup_job.rb
new file mode 100644
index 0000000..96574a7
--- /dev/null
+++ b/app/models/backup_job.rb
@@ -0,0 +1,51 @@
+class BackupJob < ActiveRecord::Base
+ attr_accessible :started_at, :finished_at, :state, :directory
+
+ mount_uploader :backup_file, BackupFileUploader
+
+ before_create :set_state_to_queued
+ after_create :initiate_backup
+
+ def to_s
+ self.started_at.to_s
+ end
+
+ private
+ def set_state_to_queued
+ self.state = 'queued'
+ self.started_at = Time.now
+ end
+
+ def initiate_backup
+ self.delay.make_a_backup
+ end
+
+ def make_a_backup
+ backup_directory = '/var/backups/GS5'
+ backup_name_prefix = 'GS5-backup-'
+ if self.finished_at.nil? && self.state == 'queued'
+ self.state = 'running'
+ self.save
+ original_directories = Dir.glob("#{backup_directory}/*")
+ system "backup perform --trigger GS5 --config_file #{Rails.root.join('config','backup.rb')}"
+ tmp_backup_directory = (Dir.glob("#{backup_directory}/*") - original_directories).first
+ if tmp_backup_directory.blank?
+ self.state = 'failed'
+ else
+ system "cd #{backup_directory} && tar czf #{backup_name_prefix}#{File.basename(tmp_backup_directory)}.tar.gz #{File.basename(tmp_backup_directory)}"
+ require 'fileutils'
+ FileUtils.rm_rf tmp_backup_directory
+ file = File::Stat.new("#{backup_directory}/#{backup_name_prefix}#{File.basename(tmp_backup_directory)}.tar.gz")
+
+ self.directory = File.basename(tmp_backup_directory)
+
+ self.backup_file = File.open("#{backup_directory}/#{backup_name_prefix}#{File.basename(tmp_backup_directory)}.tar.gz")
+
+ self.finished_at = Time.now
+ self.state = 'successful'
+ end
+ self.save
+ end
+ end
+
+end
diff --git a/app/models/call.rb b/app/models/call.rb
index 57961ec..c0f0f08 100644
--- a/app/models/call.rb
+++ b/app/models/call.rb
@@ -1,36 +1,72 @@
class Call < ActiveRecord::Base
- self.table_name = 'channels'
+ self.table_name = 'detailed_calls'
self.primary_key = 'uuid'
- # Makes sure that this is a readonly model.
def readonly?
return true
end
-
- # Prevent objects from being destroyed
- def before_destroy
- raise ActiveRecord::ReadOnlyRecord
- end
- # Prevent objects from being deleted
- def self.delete_all
- raise ActiveRecord::ReadOnlyRecord
+ def destroy
+ return self.delete
end
- # Prevent objects from being deleted
def delete
- raise ActiveRecord::ReadOnlyRecord
+ require 'freeswitch_event'
+ return FreeswitchAPI.execute('uuid_kill', self.uuid, true);
end
def sip_account
- auth_name = self.name.match('^.+[/:](.+)@.+$')
- if auth_name && ! auth_name[1].blank?
- return SipAccount.where(:auth_name => auth_name[1]).first
+ result = self.presence_id.match('^(.+)@(.+)$')
+
+ if result && ! result[1].blank? and ! result[2].blank?
+ domain = SipDomain.where(:host => result[2]).first
+ if domain
+ return SipAccount.where(:auth_name => result[1], :sip_domain_id => domain.id).first
+ end
end
end
- def kill
+ def sip_account_bleg
+ result = self.b_presence_id.match('^(.+)@(.+)$')
+
+ if result && ! result[1].blank? and ! result[2].blank?
+ domain = SipDomain.where(:host => result[2]).first
+ if domain
+ return SipAccount.where(:auth_name => result[1], :sip_domain_id => domain.id).first
+ end
+ end
+ end
+
+ def get_variable_from_uuid(channel_uuid, variable_name)
+ if channel_uuid.blank?
+ return nil
+ end
+
require 'freeswitch_event'
- return FreeswitchAPI.execute('uuid_kill', self.uuid, true);
+ result = FreeswitchAPI.channel_variable_get(channel_uuid, variable_name);
+
+ if result == '_undef_'
+ return nil
+ end
+
+ return result
+ end
+
+ def get_variable(variable_name)
+ return get_variable_from_uuid(self.uuid, variable_name);
+ end
+
+ def get_variable_bleg(variable_name)
+ return get_variable_from_uuid(self.b_uuid, variable_name);
+ end
+
+ def is_sip
+ return self.name.match('^sofia') != nil
+ end
+
+ def is_caller
+ if (self.uuid == self.call_uuid) || self.call_uuid.blank?
+ true
+ end
end
end
diff --git a/app/models/call_forward.rb b/app/models/call_forward.rb
index 8a8d1df..c668993 100644
--- a/app/models/call_forward.rb
+++ b/app/models/call_forward.rb
@@ -145,7 +145,7 @@ class CallForward < ActiveRecord::Base
softkey_function_deactivated = SoftkeyFunction.find_by_name('deactivated')
self.softkeys.each do |softkey|
if softkey.softkey_function_id != softkey_function_deactivated.id
- softkey.update_attributes(:call_forward_id => nil, :softkey_function_id => softkey_function_deactivated.id)
+ softkey.update_attributes(:softkeyable_id => nil, :softkeyable_type => nil, :softkey_function_id => softkey_function_deactivated.id)
end
end
end
diff --git a/app/models/call_route.rb b/app/models/call_route.rb
index b4496ab..8bc811a 100644
--- a/app/models/call_route.rb
+++ b/app/models/call_route.rb
@@ -2,9 +2,9 @@ class CallRoute < ActiveRecord::Base
# https://github.com/rails/strong_parameters
include ActiveModel::ForbiddenAttributesProtection
- ROUTING_TABLES = ['prerouting', 'outbound', 'inbound']
+ ROUTING_TABLES = ['prerouting', 'outbound', 'inbound', 'dtmf']
- has_many :route_elements, :dependent => :destroy
+ has_many :route_elements, :dependent => :destroy, :order => :position
validates :name,
:presence => true
@@ -239,6 +239,10 @@ class CallRoute < ActiveRecord::Base
end
end
+ def endpoint_str
+ "#{endpoint_type}=#{endpoint_id}"
+ end
+
def endpoint
if self.endpoint_id.to_i > 0
begin
diff --git a/app/models/gateway.rb b/app/models/gateway.rb
index a8df41f..2f17b57 100644
--- a/app/models/gateway.rb
+++ b/app/models/gateway.rb
@@ -1,10 +1,12 @@
class Gateway < ActiveRecord::Base
TECHNOLOGIES = ['sip', 'xmpp']
+ GATEWAY_PREFIX = 'gateway'
attr_accessible :name, :technology, :inbound, :outbound, :description
has_many :gateway_settings, :dependent => :destroy
has_many :gateway_parameters, :dependent => :destroy
+ has_many :call_routes, :as => :endpoint, :dependent => :nullify
validates :name,
:presence => true,
@@ -21,6 +23,10 @@ class Gateway < ActiveRecord::Base
name
end
+ def identifier
+ "#{GATEWAY_PREFIX}#{self.id}"
+ end
+
private
def downcase_technology
self.technology = self.technology.downcase if !self.technology.blank?
diff --git a/app/models/gateway_setting.rb b/app/models/gateway_setting.rb
index e3eaadb..381dde5 100644
--- a/app/models/gateway_setting.rb
+++ b/app/models/gateway_setting.rb
@@ -10,6 +10,7 @@ class GatewaySetting < ActiveRecord::Base
'auth_source' => 'String',
'auth_pattern' => 'String',
'number_source' => 'String',
+ 'profile' => 'String',
},
'xmpp' => {
'server' => 'String',
diff --git a/app/models/intruder.rb b/app/models/intruder.rb
new file mode 100644
index 0000000..db14bf8
--- /dev/null
+++ b/app/models/intruder.rb
@@ -0,0 +1,37 @@
+class Intruder < ActiveRecord::Base
+ attr_accessible :list_type, :key, :points, :bans, :ban_last, :ban_end, :contact_ip, :contact_port, :contact_count, :contact_last, :contacts_per_second, :contacts_per_second_max, :user_agent, :to_user, :comment
+
+ LIST_TYPES = ['blacklist', 'whitelist']
+
+ validates :list_type,
+ :presence => true,
+ :inclusion => { :in => LIST_TYPES }
+
+ validates :key,
+ :presence => true,
+ :uniqueness => true
+
+ validates :contact_ip,
+ :presence => true,
+ :uniqueness => true
+
+ before_validation :set_key_if_empty
+
+
+ def whois
+ if ! self.contact_ip.blank?
+ begin
+ return Whois.whois(self.contact_ip)
+ rescue
+ return nil
+ end
+ end
+ end
+
+ private
+ def set_key_if_empty
+ if self.key.blank?
+ self.key = self.contact_ip
+ end
+ end
+end
diff --git a/app/models/sip_account.rb b/app/models/sip_account.rb
index 444eb12..9ba1f8b 100644
--- a/app/models/sip_account.rb
+++ b/app/models/sip_account.rb
@@ -21,7 +21,7 @@ class SipAccount < ActiveRecord::Base
belongs_to :tenant
belongs_to :sip_domain
- has_many :softkeys, :dependent => :destroy
+ has_many :softkeys, :dependent => :destroy, :order => :position
has_many :voicemail_messages, :foreign_key => 'username', :primary_key => 'auth_name'
diff --git a/app/models/softkey.rb b/app/models/softkey.rb
index a709036..83c88ab 100644
--- a/app/models/softkey.rb
+++ b/app/models/softkey.rb
@@ -1,13 +1,11 @@
class Softkey < ActiveRecord::Base
- attr_accessible :softkey_function_id, :number, :label, :call_forward_id, :uuid
+ attr_accessible :softkey_function_id, :number, :label, :uuid, :softkeyable_type, :softkeyable_id
belongs_to :sip_account
belongs_to :softkey_function
- belongs_to :call_forward
+ belongs_to :softkeyable, :polymorphic => true
- # Any CallForward BLF must have a valid softkey_call_forward_id.
- #
- validates_presence_of :call_forward_id, :if => Proc.new{ |softkey| self.softkey_function_id != nil &&
+ 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.
@@ -21,7 +19,6 @@ class Softkey < ActiveRecord::Base
acts_as_list :scope => :sip_account
before_validation :clean_up_and_leave_only_values_which_make_sense_for_the_current_softkey_function_id
- after_validation :save_function_name_in_function, :if => Proc.new{ |softkey| self.call_forward_id.blank? }
after_save :resync_phone
after_destroy :resync_phone
@@ -52,7 +49,7 @@ class Softkey < ActiveRecord::Base
def to_s
if (['call_forwarding'].include?(self.softkey_function.name))
- "#{self.call_forward}"
+ "#{self.softkeyable}"
else
if ['log_out', 'log_in'].include?(self.softkey_function.name)
I18n.t("softkeys.functions.#{self.softkey_function.name}")
@@ -78,21 +75,22 @@ class Softkey < ActiveRecord::Base
end
private
-
- def save_function_name_in_function
- self.function = self.softkey_function.name
- end
-
# 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.
#
def clean_up_and_leave_only_values_which_make_sense_for_the_current_softkey_function_id
- if self.softkey_function_id != nil
- if ['blf','speed_dial','dtmf','conference'].include?(self.softkey_function.name)
- self.call_forward_id = nil
- end
- if ['call_forwarding'].include?(self.softkey_function.name)
+ if self.softkey_function_id != nil
+ case self.softkey_function.name
+ when 'blf'
+ self.softkeyable = PhoneNumber.where(:number => self.number, :phone_numberable_type => 'SipAccount').first.try(:phone_numberable)
+ when 'conference'
+ self.softkeyable = PhoneNumber.where(:number => self.number, :phone_numberable_type => 'Conference').first.try(:phone_numberable)
+ when 'call_forwarding'
+ self.softkeyable = CallForward.where(:id => self.softkeyable_id).first
self.number = nil
+ else
+ self.softkeyable_id = nil
+ self.softkeyable_type = nil
end
end
end
diff --git a/app/models/system_message.rb b/app/models/system_message.rb
deleted file mode 100644
index 0d9e862..0000000
--- a/app/models/system_message.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class SystemMessage < ActiveRecord::Base
- attr_accessible :content
-
- belongs_to :user
-
- validates_presence_of :content
-end
diff --git a/app/uploaders/backup_file_uploader.rb b/app/uploaders/backup_file_uploader.rb
new file mode 100644
index 0000000..8b126a9
--- /dev/null
+++ b/app/uploaders/backup_file_uploader.rb
@@ -0,0 +1,55 @@
+# encoding: utf-8
+
+class BackupFileUploader < CarrierWave::Uploader::Base
+
+ # Include RMagick or MiniMagick support:
+ # include CarrierWave::RMagick
+ # include CarrierWave::MiniMagick
+
+ # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
+ # include Sprockets::Helpers::RailsHelper
+ # include Sprockets::Helpers::IsolatedHelper
+
+ # Choose what kind of storage to use for this uploader:
+ storage :file
+ # storage :fog
+
+ # Override the directory where uploaded files will be stored.
+ # This is a sensible default for uploaders that are meant to be mounted:
+ def store_dir
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
+ end
+
+ # Provide a default URL as a default if there hasn't been a file uploaded:
+ # def default_url
+ # # For Rails 3.1+ asset pipeline compatibility:
+ # # asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
+ #
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
+ # end
+
+ # Process files as they are uploaded:
+ # process :scale => [200, 300]
+ #
+ # def scale(width, height)
+ # # do something
+ # end
+
+ # Create different versions of your uploaded files:
+ # version :thumb do
+ # process :scale => [50, 50]
+ # end
+
+ # Add a white list of extensions which are allowed to be uploaded.
+ # For images you might use something like this:
+ # def extension_white_list
+ # %w(jpg jpeg gif png)
+ # end
+
+ # Override the filename of the uploaded files:
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
+ # def filename
+ # "something.jpg" if original_filename
+ # end
+
+end
diff --git a/app/views/backup_jobs/_form.html.haml b/app/views/backup_jobs/_form.html.haml
new file mode 100644
index 0000000..e0adceb
--- /dev/null
+++ b/app/views/backup_jobs/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for(@backup_job) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('backup_jobs.form.submit') \ No newline at end of file
diff --git a/app/views/backup_jobs/_form_core.html.haml b/app/views/backup_jobs/_form_core.html.haml
new file mode 100644
index 0000000..9d439c5
--- /dev/null
+++ b/app/views/backup_jobs/_form_core.html.haml
@@ -0,0 +1,5 @@
+.inputs
+ = f.input :started_at, :label => t('backup_jobs.form.started_at.label'), :hint => conditional_hint('backup_jobs.form.started_at.hint')
+ = f.input :finished_at, :label => t('backup_jobs.form.finished_at.label'), :hint => conditional_hint('backup_jobs.form.finished_at.hint')
+ = f.input :state, :label => t('backup_jobs.form.state.label'), :hint => conditional_hint('backup_jobs.form.state.hint')
+ = f.input :directory, :label => t('backup_jobs.form.directory.label'), :hint => conditional_hint('backup_jobs.form.directory.hint')
diff --git a/app/views/backup_jobs/_index_core.html.haml b/app/views/backup_jobs/_index_core.html.haml
new file mode 100644
index 0000000..0102546
--- /dev/null
+++ b/app/views/backup_jobs/_index_core.html.haml
@@ -0,0 +1,49 @@
+%table.table.table-striped
+ %tr
+ %th= t('backup_jobs.index.started_at')
+ %th
+ %span.hidden-phone
+ = t('backup_jobs.index.finished_at')
+ %th= t('backup_jobs.index.state')
+ %th
+ %span.hidden-phone
+ = t('backup_jobs.index.size_of_the_backup')
+ %th{:colspan => '2'}
+
+ - for backup_job in backup_jobs
+ - if backup_job.state == 'queued'
+ - row_marker = 'warning'
+ - else
+ - if backup_job.state == 'failed'
+ - row_marker = 'error'
+ - else
+ - row_marker = ''
+ %tr{:class => row_marker}
+ - if backup_job.finished_at.blank?
+ %td{:colspan => '2'}
+ - if (Time.now - 1.day) > backup_job.started_at
+ = l backup_job.started_at, :format => :short
+ - else
+ - case I18n.locale
+ - when :de
+ = "vor #{time_ago_in_words(backup_job.started_at)}"
+ - when :en
+ = "#{time_ago_in_words(backup_job.started_at)} ago"
+ - else
+ = l backup_job.started_at, :format => :short
+ - else
+ %td
+ = l backup_job.started_at, :format => :short
+ %td
+ %span.hidden-phone
+ = l backup_job.finished_at, :format => :short
+ %td= backup_job.state
+ %td
+ %span.hidden-phone
+ - if backup_job.backup_file?
+ %a{:href => backup_job.backup_file.url}
+ %i{:class => 'icon-download'}
+ = number_to_human_size(backup_job.backup_file.size, :precision => 2)
+ - else
+ = '-'
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => backup_job}
diff --git a/app/views/backup_jobs/edit.html.haml b/app/views/backup_jobs/edit.html.haml
new file mode 100644
index 0000000..7892edb
--- /dev/null
+++ b/app/views/backup_jobs/edit.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("backup_jobs.edit.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/backup_jobs/index.html.haml b/app/views/backup_jobs/index.html.haml
new file mode 100644
index 0000000..0bb4747
--- /dev/null
+++ b/app/views/backup_jobs/index.html.haml
@@ -0,0 +1,6 @@
+- content_for :title, t("backup_jobs.index.page_title")
+
+- if @backup_jobs && @backup_jobs.count > 0
+ = render "index_core", :backup_jobs => @backup_jobs
+
+= render :partial => 'shared/create_link', :locals => {:child_class => BackupJob} \ No newline at end of file
diff --git a/app/views/backup_jobs/new.html.haml b/app/views/backup_jobs/new.html.haml
new file mode 100644
index 0000000..65efd4f
--- /dev/null
+++ b/app/views/backup_jobs/new.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("backup_jobs.new.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/backup_jobs/show.html.haml b/app/views/backup_jobs/show.html.haml
new file mode 100644
index 0000000..6fcb1dc
--- /dev/null
+++ b/app/views/backup_jobs/show.html.haml
@@ -0,0 +1,22 @@
+- content_for :title, t("backup_jobs.show.page_title")
+
+%p
+ %strong= t('backup_jobs.show.started_at') + ":"
+ = @backup_job.started_at
+%p
+ %strong= t('backup_jobs.show.finished_at') + ":"
+ = @backup_job.finished_at
+%p
+ %strong= t('backup_jobs.show.state') + ":"
+ = @backup_job.state
+%p
+ %strong= t('backup_jobs.show.directory') + ":"
+ = @backup_job.directory
+%p
+ %strong= t('backup_jobs.show.size_of_the_backup') + ":"
+ - if @backup_job.backup_file?
+ %a{:href => backup_job.backup_file.url}
+ %i{:class => 'icon-download'}
+ = number_to_human_size(backup_job.backup_file.size, :precision => 2)
+
+= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @backup_job } \ No newline at end of file
diff --git a/app/views/call_histories/_index_core.html.haml b/app/views/call_histories/_index_core.html.haml
index 4ca340d..8bbf761 100644
--- a/app/views/call_histories/_index_core.html.haml
+++ b/app/views/call_histories/_index_core.html.haml
@@ -22,7 +22,7 @@
- phone_book_entry = call_history.phone_book_entry_by_number(call_history.display_number)
%tr{:id => "call_history_id_#{call_history.id}_tr", :class => (call_history.duration.blank? ? 'warning' : '')}
%td
- = l call_history.start_stamp, :format => :date_only
+ = l call_history.start_stamp, :format => :short
%td
= l call_history.start_stamp, :format => :short
%td
diff --git a/app/views/call_routes/_form_core.html.haml b/app/views/call_routes/_form_core.html.haml
index b64d660..926c985 100644
--- a/app/views/call_routes/_form_core.html.haml
+++ b/app/views/call_routes/_form_core.html.haml
@@ -1,5 +1,5 @@
.inputs
= f.input :routing_table, :collection => CallRoute::ROUTING_TABLES, :label => t('call_routes.form.table.label'), :hint => conditional_hint('call_routes.form.table.hint'), :include_blank => false, :autofocus => true
= f.input :name, :label => t('call_routes.form.name.label'), :hint => conditional_hint('call_routes.form.name.hint')
- = f.input :endpoint_type, :label => t('call_routes.form.endpoint_type.label'), :hint => conditional_hint('call_routes.form.endpoint_type.hint')
- = f.input :endpoint_id, :label => t('call_routes.form.endpoint_id.label'), :hint => conditional_hint('call_routes.form.endpoint_id.hint')
+ = f.input :endpoint_str, :collection => @endpoints, :label => t('call_routes.form.endpoint.label'), :hint => conditional_hint('call_routes.form.endpoint.hint'), :include_blank => false
+ = f.input :position, :label => t('call_routes.form.position.label'), :hint => conditional_hint('call_routes.form.position.hint') \ No newline at end of file
diff --git a/app/views/call_routes/_index_core.html.haml b/app/views/call_routes/_index_core.html.haml
index f0acebb..a62a9c4 100644
--- a/app/views/call_routes/_index_core.html.haml
+++ b/app/views/call_routes/_index_core.html.haml
@@ -1,15 +1,19 @@
-- cache(['call_routes_table', call_routes.count, call_routes.reorder(:updated_at).last]) do
+- cache(['call_routes_table', I18n.locale, call_routes.count, call_routes.reorder(:updated_at).last]) do
%table.table.table-striped
%thead
%tr
+ %th
%th= t('call_routes.index.name')
%th= t('route_elements.index.pattern')
%th= t('call_routes.index.endpoint')
- %tbody
+ %tbody{ :class => "call_routes", :id => "call_routes_#{routing_table}", :'data-update-url' => sort_call_routes_url}
- for call_route in call_routes
- - cache(['call_route_single_table_row', call_route, call_routes.count]) do
- %tr
+ - cache(['call_route_single_table_row', I18n.locale, call_route]) do
+ = content_tag_for :tr, call_route do
+ %td
+ %span.handle
+ %i.icon-resize-vertical
%td= call_route.name
%td
- if call_route.route_elements.any?
diff --git a/app/views/call_routes/index.html.haml b/app/views/call_routes/index.html.haml
index 488e1c7..0108322 100644
--- a/app/views/call_routes/index.html.haml
+++ b/app/views/call_routes/index.html.haml
@@ -1,11 +1,8 @@
- content_for :title, t("call_routes.index.page_title")
-- if @call_routes && @call_routes.count > 0
- %table.table.table-striped
- - @routing_tables.each do |routing_table|
- %tr
- %td{:colspan => 3}
- %h3= routing_table
- = render "index_core", :call_routes => @call_routes.where(:routing_table => routing_table)
+- if @call_routes && @call_routes.any?
+ - @routing_tables.each do |routing_table|
+ %h3= routing_table
+ = render "index_core", :call_routes => @call_routes.where(:routing_table => routing_table), :routing_table => routing_table
= render :partial => 'shared/create_link', :locals => {:child_class => CallRoute}
diff --git a/app/views/call_routes/show.html.haml b/app/views/call_routes/show.html.haml
index 09daf53..7c695c8 100644
--- a/app/views/call_routes/show.html.haml
+++ b/app/views/call_routes/show.html.haml
@@ -1,23 +1,33 @@
- content_for :title, t("call_routes.show.page_title")
-%p
- %strong= t('call_routes.show.table') + ":"
- = @call_route.routing_table
-%p
- %strong= t('call_routes.show.name') + ":"
- = @call_route.name
-%p
- %strong= t('call_routes.show.endpoint') + ":"
- - endpoint = @call_route.endpoint
- - if endpoint
- = endpoint
- - else
- = @call_route.endpoint_type
+.row
+ .span5
+ %table.table.table-striped
+ %tr
+ %td
+ %strong= t('call_routes.show.table') + ":"
+ %td
+ = @call_route.routing_table
+ %tr
+ %td
+ %strong= t('call_routes.show.name') + ":"
+ %td
+ = @call_route.name
+ %tr
+ %td
+ %strong= t('call_routes.show.endpoint') + ":"
+ %td
+ - if @call_route.endpoint.blank?
+ = @call_route.endpoint_type
+ - else
+ = @call_route.endpoint
-= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @call_route }
+ = render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @call_route }
-%h3= t('route_elements.index.page_title')
-- if @call_route.route_elements && @call_route.route_elements.count > 0
- = render "route_elements/index_core", :route_elements => @call_route.route_elements
+.row
+ .span12
+ %h3= t('route_elements.index.page_title')
+ - if @call_route.route_elements && @call_route.route_elements.count > 0
+ = render "route_elements/index_core", :route_elements => @call_route.route_elements
-= render :partial => 'shared/create_link', :locals => { :parent => @call_route, :child_class => RouteElement }
+ = render :partial => 'shared/create_link', :locals => { :parent => @call_route, :child_class => RouteElement }
diff --git a/app/views/call_routes/show.xml.haml b/app/views/call_routes/show.xml.haml
new file mode 100644
index 0000000..5800816
--- /dev/null
+++ b/app/views/call_routes/show.xml.haml
@@ -0,0 +1,5 @@
+!!! XML
+%call_route{ :name => @call_route.name, :routing_table => @call_route.routing_table, :position => @call_route.position, :endpoint => @call_route.endpoint, :endpoint_type => @call_route.endpoint_type }
+ %route_elements{ :count => @call_route.route_elements.count }
+ - @call_route.route_elements.each do |route_element|
+ %route_element{ :var_in => route_element.var_in, :var_out => route_element.var_out, :pattern => route_element.pattern, :replacement => route_element.replacement, :action => route_element.action, :mandatory => route_element.mandatory.to_s, :position => route_element.position }
diff --git a/app/views/call_routes/show_variables.html.haml b/app/views/call_routes/show_variables.html.haml
new file mode 100644
index 0000000..4bec39d
--- /dev/null
+++ b/app/views/call_routes/show_variables.html.haml
@@ -0,0 +1,13 @@
+%h3= 'Channel Variables'
+
+%table.table.table-striped
+ %thead
+ %tr
+ %th= 'Variable'
+ %th= 'Value'
+
+ %tbody{ :id => "show_variables" }
+ - @channel_variables.each do |key, value|
+ %tr
+ %td= key
+ %td= value.gsub(/\n/, '<br/>').html_safe
diff --git a/app/views/config_snom/show.xml.haml b/app/views/config_snom/show.xml.haml
index 5f53802..33204dc 100644
--- a/app/views/config_snom/show.xml.haml
+++ b/app/views/config_snom/show.xml.haml
@@ -40,7 +40,11 @@
%mwi_notification{:perm => 'RW'}= 'silent'
%mwi_dialtone{:perm => 'RW'}= 'normal'
%prefer_saved_over_received_photo{:perm => 'RW'}= 'off'
- %no_dnd{:perm => 'RW'}= 'on'
+ %no_dnd{:perm => 'RW'}= 'off'
+ %transfer_on_hangup{:perm => 'RW'}= 'on'
+ %transfer_on_hangup_non_pots{:perm => 'RW'}= 'off'
+ %call_join_xfer{:perm => 'RW'}= 'on'
+ %conf_hangup{:perm => 'RW'}= 'on'
%logon_wizard{:perm => 'RW'}= 'off'
%disable_deflection{:perm => 'RW'}= 'off'
%csta_control{:perm => 'RW'}= 'on'
@@ -117,7 +121,7 @@
%user_realname{:idx => index, :perm => 'R'}= sip_account[:realname]
%user_idle_text{:idx => index, :perm => 'R'}= sip_account[:idle_text]
%user_mailbox{:idx => index, :perm => 'R'}= sip_account[:mailbox]
- %user_expiry{:idx => index, :perm => 'R'}= ''
+ %user_expiry{:idx => index, :perm => 'R'}= sip_account[:expiry]
%user_server_type{:idx => index, :perm => 'R'}= 'default'
%user_send_local_name{:idx => index, :perm => 'RW'}= 'on'
%user_dtmf_info{:idx => index, :perm => 'RW'}= 'off'
diff --git a/app/views/fax_accounts/_index_core.html.haml b/app/views/fax_accounts/_index_core.html.haml
index d694f8f..846cda8 100644
--- a/app/views/fax_accounts/_index_core.html.haml
+++ b/app/views/fax_accounts/_index_core.html.haml
@@ -39,8 +39,8 @@
= time_ago_in_words(fax_account.fax_documents.order(:updated_at).last.updated_at)
%td
- if can?(:new, FaxDocument, :fax_account_id => fax_account.id)
- %a.btn.btn-mini.btn-primary{:href => new_fax_account_fax_document_path(fax_account) }
- %i.icon-print.icon-white
+ %a.btn.btn-small{:href => new_fax_account_fax_document_path(fax_account) }
+ %i.icon-print
%span.hidden-phone
=t('fax_accounts.index.send_a_fax')
diff --git a/app/views/fax_accounts/show.html.haml b/app/views/fax_accounts/show.html.haml
index 1a32121..454ebee 100644
--- a/app/views/fax_accounts/show.html.haml
+++ b/app/views/fax_accounts/show.html.haml
@@ -12,7 +12,11 @@
= render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @parent, :child => @fax_account }
-= render :partial => 'shared/create_link', :locals => { :parent => @fax_account, :child_class => FaxDocument }
+%p
+ %a.btn.btn-small{:href => new_fax_account_fax_document_path(@fax_account) }
+ %i.icon-print
+ %span.hidden-phone
+ =t('fax_accounts.index.send_a_fax')
%h2= t('phone_numbers.index.page_title')
- if @fax_account.phone_numbers.count > 0
diff --git a/app/views/gateways/show.xml.haml b/app/views/gateways/show.xml.haml
new file mode 100644
index 0000000..e0ff21a
--- /dev/null
+++ b/app/views/gateways/show.xml.haml
@@ -0,0 +1,17 @@
+!!! XML
+%gateway{ :identifier => @gateway.identifier, :name => @gateway.name, :technology => @gateway.technology, :inbound => @gateway.inbound.to_s, :outbound => @gateway.outbound.to_s, :description => @gateway.description }
+
+ %gateway_settings{ :count => @gateway.gateway_settings.count }
+ - @gateway.gateway_settings.each do |setting|
+ %setting{ :name => setting.name, :value => setting.value, :class_type => setting.class_type, :description => setting.description }
+
+ %gateway_parameters{ :count => @gateway.gateway_parameters.count }
+ - @gateway.gateway_parameters.each do |parameter|
+ %parameter{ :name => parameter.name, :value => parameter.value, :class_type => parameter.class_type, :description => parameter.description }
+
+ %call_routes{ :count => @gateway.call_routes.count }
+ - @gateway.call_routes.each do |call_route|
+ %call_route{ :name => call_route.name, :routing_table => call_route.routing_table, :position => call_route.position }
+ %route_elements{ :count => call_route.route_elements.count }
+ - call_route.route_elements.each do |route_element|
+ %route_element{ :var_in => route_element.var_in, :var_out => route_element.var_out, :pattern => route_element.pattern, :replacement => route_element.replacement, :action => route_element.action, :mandatory => route_element.mandatory.to_s, :position => route_element.position }
diff --git a/app/views/gemeinschaft_setups/new.de.html.haml b/app/views/gemeinschaft_setups/new.de.html.haml
index cf1f207..f977291 100644
--- a/app/views/gemeinschaft_setups/new.de.html.haml
+++ b/app/views/gemeinschaft_setups/new.de.html.haml
@@ -14,6 +14,7 @@
= f.association :country, :label => t('gemeinschaft_setups.form.country_id.label'), :hint => conditional_hint('gemeinschaft_setups.form.country_id.hint'), :include_blank => false
= f.association :language, :label => t('gemeinschaft_setups.form.language_id.label'), :hint => conditional_hint('gemeinschaft_setups.form.language_id.hint'), :include_blank => false
= f.input :default_area_code, :label => t('gemeinschaft_setups.form.default_area_code.label'), :hint => conditional_hint('gemeinschaft_setups.form.default_area_code.hint')
+ = f.input :trunk_access_code, :label => t('gemeinschaft_setups.form.trunk_access_code.label'), :hint => conditional_hint('gemeinschaft_setups.form.trunk_access_code.hint')
= f.input :default_company_name, :label => t('gemeinschaft_setups.form.default_company_name.label'), :hint => conditional_hint('gemeinschaft_setups.form.default_company_name.hint')
diff --git a/app/views/gemeinschaft_setups/new.html.haml b/app/views/gemeinschaft_setups/new.html.haml
index 5e2434e..44d9c5b 100644
--- a/app/views/gemeinschaft_setups/new.html.haml
+++ b/app/views/gemeinschaft_setups/new.html.haml
@@ -14,6 +14,7 @@
= f.association :country, :label => t('gemeinschaft_setups.form.country_id.label'), :hint => conditional_hint('gemeinschaft_setups.form.country_id.hint'), :include_blank => false
= f.association :language, :label => t('gemeinschaft_setups.form.language_id.label'), :hint => conditional_hint('gemeinschaft_setups.form.language_id.hint'), :include_blank => false
= f.input :default_area_code, :label => t('gemeinschaft_setups.form.default_area_code.label'), :hint => conditional_hint('gemeinschaft_setups.form.default_area_code.hint')
+ = f.input :trunk_access_code, :label => t('gemeinschaft_setups.form.trunk_access_code.label'), :hint => conditional_hint('gemeinschaft_setups.form.trunk_access_code.hint')
= f.input :default_company_name, :label => t('gemeinschaft_setups.form.default_company_name.label'), :hint => conditional_hint('gemeinschaft_setups.form.default_company_name.hint')
diff --git a/app/views/gs_nodes/sync.xml.haml b/app/views/gs_nodes/sync.xml.haml
index 0f097f8..a2fa71a 100644
--- a/app/views/gs_nodes/sync.xml.haml
+++ b/app/views/gs_nodes/sync.xml.haml
@@ -60,7 +60,7 @@
- if !@softkeys.blank?
%softkeys
- @softkeys.each do |softkey|
- %softkey{ :uuid => softkey.uuid, :function => softkey.softkey_function.try(:name), :number => softkey.number, :label => softkey.label, :position => softkey.position, :created_at => softkey.created_at, :updated_at => softkey.updated_at, :sip_account_uuid => softkey.sip_account.try(:uuid), :call_forward_uuid => softkey.call_forward.try(:uuid) }
+ %softkey{ :uuid => softkey.uuid, :function => softkey.softkey_function.try(:name), :number => softkey.number, :label => softkey.label, :position => softkey.position, :created_at => softkey.created_at, :updated_at => softkey.updated_at, :sip_account_uuid => softkey.sip_account.try(:uuid), :softkeyable_uuid => softkey.softkeyable.try(:uuid), :softkeyable_type => softkey.softkeyable_type) }
- if !@ringtones.blank?
%ringtones
diff --git a/app/views/gs_parameters/_index_core.html.haml b/app/views/gs_parameters/_index_core.html.haml
index 11d60db..2105126 100644
--- a/app/views/gs_parameters/_index_core.html.haml
+++ b/app/views/gs_parameters/_index_core.html.haml
@@ -1,6 +1,9 @@
-- cache(['gs_parameters_table_section', gs_parameters.first.section, gs_parameters.reorder(:updated_at).last, gs_parameters.pluck(:id)]) do
+- cache(['gs_parameter_sub_table', I18n.locale, gs_parameters.count, gs_parameters.reorder(:updated_at).first, gs_parameters.reorder(:updated_at).last]) do
%thead
%tr
+ %th
+ %span.hidden-phone
+ = t('gs_parameters.index.entity')
%th= t('gs_parameters.index.name')
- if !@sections
%th= t('gs_parameters.index.section')
@@ -8,9 +11,16 @@
%tbody
- for gs_parameter in gs_parameters
- - cache(['gs_parameters_table_single_row', gs_parameter]) do
+ - cache(['gs_parameters_table_single_row', I18n.locale, gs_parameter]) do
%tr
%td
+ - if gs_parameter.entity.blank?
+ %span.hidden-phone
+ = '-'
+ - else
+ %span.hidden-phone
+ = truncate(gs_parameter.entity, :length => GsParameter.get('DESKTOP_MAX_STRING_LENGTH'))
+ %td
%span.hidden-phone
= truncate(gs_parameter.name, :length => GsParameter.get('DESKTOP_MAX_STRING_LENGTH'))
%span.visible-phone
diff --git a/app/views/gs_parameters/index.html.haml b/app/views/gs_parameters/index.html.haml
index 1189a45..8df2bb3 100644
--- a/app/views/gs_parameters/index.html.haml
+++ b/app/views/gs_parameters/index.html.haml
@@ -1,13 +1,11 @@
- content_for :title, t("gs_parameters.index.page_title")
-- if @gs_parameters && @gs_parameters.count > 0
- - cache(['gs_parameters_table', I18n.locale, @gs_parameters_unordered.reorder(:updated_at).last, @gs_parameters_unordered.count]) do
+- cache(['gs_parameter_all_tables', I18n.locale, @gs_parameters.count, @gs_parameters.reorder(:updated_at).first, @gs_parameters.reorder(:updated_at).last]) do
+ - if @gs_parameters && @gs_parameters.count > 0
- if @sections
- %table.table.table-striped
- - @sections.each do |section|
- %tr
- %td{:colspan => 3}
- %h3= section
+ - @sections.each do |section|
+ %h3= section
+ %table.table.table-striped
-# Template Dependency: gs_parameters/_index_core
= render "index_core", :gs_parameters => @gs_parameters.where(:section => section)
- else
diff --git a/app/views/intruders/_form.html.haml b/app/views/intruders/_form.html.haml
new file mode 100644
index 0000000..26aab1c
--- /dev/null
+++ b/app/views/intruders/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for(@intruder) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('intruders.form.submit') \ No newline at end of file
diff --git a/app/views/intruders/_form_core.html.haml b/app/views/intruders/_form_core.html.haml
new file mode 100644
index 0000000..780d8cd
--- /dev/null
+++ b/app/views/intruders/_form_core.html.haml
@@ -0,0 +1,5 @@
+.inputs
+ = f.input :list_type, :collection => Intruder::LIST_TYPES, :label => t('intruders.form.list_type.label'), :hint => conditional_hint('intruders.form.list_type.hint'), :include_blank => false
+ = f.input :contact_ip, :label => t('intruders.form.contact_ip.label'), :hint => conditional_hint('intruders.form.contact_ip.hint')
+ = f.input :ban_end, :label => t('intruders.form.ban_end.label'), :hint => conditional_hint('intruders.form.ban_end.hint')
+ = f.input :comment, :label => t('intruders.form.comment.label'), :hint => conditional_hint('intruders.form.comment.hint')
diff --git a/app/views/intruders/_index_core.html.haml b/app/views/intruders/_index_core.html.haml
new file mode 100644
index 0000000..0070c4d
--- /dev/null
+++ b/app/views/intruders/_index_core.html.haml
@@ -0,0 +1,37 @@
+%table.table.table-striped
+ %tr
+ %th= t('intruders.index.list_type')
+ %th= t('intruders.index.key')
+ %th= t('intruders.index.points')
+ %th= t('intruders.index.bans')
+ %th= t('intruders.index.ban_last')
+ %th= t('intruders.index.ban_end')
+ %th= t('intruders.index.contact_ip')
+ %th= t('intruders.index.contact_port')
+ %th= t('intruders.index.contact_count')
+ %th= t('intruders.index.contact_last')
+ %th= t('intruders.index.contacts_per_second')
+ %th= t('intruders.index.contacts_per_second_max')
+ %th= t('intruders.index.user_agent')
+ %th= t('intruders.index.to_user')
+ %th= t('intruders.index.comment')
+
+
+ - for intruder in intruders
+ %tr
+ %td= intruder.list_type
+ %td= intruder.key
+ %td= intruder.points
+ %td= intruder.bans
+ %td= intruder.ban_last
+ %td= intruder.ban_end
+ %td= intruder.contact_ip
+ %td= intruder.contact_port
+ %td= intruder.contact_count
+ %td= intruder.contact_last
+ %td= intruder.contacts_per_second
+ %td= intruder.contacts_per_second_max
+ %td= intruder.user_agent
+ %td= intruder.to_user
+ %td= intruder.comment
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => intruder} \ No newline at end of file
diff --git a/app/views/intruders/edit.html.haml b/app/views/intruders/edit.html.haml
new file mode 100644
index 0000000..1b5a31b
--- /dev/null
+++ b/app/views/intruders/edit.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("intruders.edit.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/intruders/index.html.haml b/app/views/intruders/index.html.haml
new file mode 100644
index 0000000..72b8882
--- /dev/null
+++ b/app/views/intruders/index.html.haml
@@ -0,0 +1,6 @@
+- content_for :title, t("intruders.index.page_title")
+
+- if @intruders && @intruders.count > 0
+ = render "index_core", :intruders => @intruders
+
+= render :partial => 'shared/create_link', :locals => {:child_class => Intruder} \ No newline at end of file
diff --git a/app/views/intruders/new.html.haml b/app/views/intruders/new.html.haml
new file mode 100644
index 0000000..a24b55f
--- /dev/null
+++ b/app/views/intruders/new.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("intruders.new.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/intruders/show.html.haml b/app/views/intruders/show.html.haml
new file mode 100644
index 0000000..4941e89
--- /dev/null
+++ b/app/views/intruders/show.html.haml
@@ -0,0 +1,52 @@
+- content_for :title, t("intruders.show.page_title")
+
+%p
+ %strong= t('intruders.show.list_type') + ":"
+ = @intruder.list_type
+%p
+ %strong= t('intruders.show.key') + ":"
+ = @intruder.key
+%p
+ %strong= t('intruders.show.points') + ":"
+ = @intruder.points
+%p
+ %strong= t('intruders.show.bans') + ":"
+ = @intruder.bans
+%p
+ %strong= t('intruders.show.ban_last') + ":"
+ = @intruder.ban_last
+%p
+ %strong= t('intruders.show.ban_end') + ":"
+ = @intruder.ban_end
+%p
+ %strong= t('intruders.show.contact_ip') + ":"
+ = @intruder.contact_ip
+%p
+ %strong= t('intruders.show.contact_port') + ":"
+ = @intruder.contact_port
+%p
+ %strong= t('intruders.show.contact_count') + ":"
+ = @intruder.contact_count
+%p
+ %strong= t('intruders.show.contact_last') + ":"
+ = @intruder.contact_last
+%p
+ %strong= t('intruders.show.contacts_per_second') + ":"
+ = @intruder.contacts_per_second
+%p
+ %strong= t('intruders.show.contacts_per_second_max') + ":"
+ = @intruder.contacts_per_second_max
+%p
+ %strong= t('intruders.show.user_agent') + ":"
+ = @intruder.user_agent
+%p
+ %strong= t('intruders.show.to_user') + ":"
+ = @intruder.to_user
+%p
+ %strong= t('intruders.show.comment') + ":"
+ = @intruder.comment
+
+%p
+ %pre= @intruder.whois
+
+= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @intruder }
diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml
index 97bf483..2703844 100644
--- a/app/views/layouts/_footer.html.haml
+++ b/app/views/layouts/_footer.html.haml
@@ -14,6 +14,6 @@
%li
= link_to 'GS5 Google Group', "https://groups.google.com/group/gs5-users/"
%li
- =link_to t('misc.send_a_bugreport'), URI::escape("https://github.com/amooma/GS5/issues/new?title=Bugreport&body=URL which triggered the bugreport is: #{request.fullpath}\nGS5 buildname: #{(GsParameter.get('GEMEINSCHAFT_BUILDNAME').blank? ? 'unknown' : GsParameter.get('GEMEINSCHAFT_BUILDNAME'))}\n\nPlease provide your bugreport below this line and update the title of this issue to a more specific one.")
+ =link_to t('misc.send_a_bugreport'), URI::escape("https://github.com/amooma/GS5/issues/new?title=Bugreport&body=URL which triggered the bugreport is: #{request.fullpath}\nGS5 buildname: #{(GsParameter.get('GEMEINSCHAFT_BUILDNAME').blank? ? 'unknown' : GsParameter.get('GEMEINSCHAFT_BUILDNAME'))} (#{GsParameter.get('GEMEINSCHAFT_VERSION')})\n\nPlease provide your bugreport below this line and update the title of this issue to a more specific one.")
%li{:class => 'pull-right'}
- = link_to 'brought to you by AMOOMA GmbH', 'http://amooma.de' \ No newline at end of file
+ = link_to '© AMOOMA GmbH', 'http://amooma.de' \ No newline at end of file
diff --git a/app/views/layouts/_navbar.html.haml b/app/views/layouts/_navbar.html.haml
index c2d9946..7084090 100644
--- a/app/views/layouts/_navbar.html.haml
+++ b/app/views/layouts/_navbar.html.haml
@@ -14,18 +14,16 @@
- if current_user && GemeinschaftSetup.any? && current_user.admin?
- if current_page?(page_help_path)
%li.active
- =link_to 'Admin-Doku', page_help_path
+ =link_to t('navigation.admin_docu'), page_help_path
- else
%li
- =link_to 'Admin-Doku', page_help_path
+ =link_to t('navigation.admin_docu'), page_help_path
- if current_user && current_user.sip_accounts.any?
%li
%a{:href => sip_account_call_histories_path(current_user.sip_accounts.first)}
- %i.icon-list-alt.icon-white
=t("call_histories.index.page_title")
%li
%a{:href => sip_account_voicemail_messages_path(current_user.sip_accounts.first)}
- %i.icon-volume-up.icon-white
=t("voicemail_messages.index.page_title")
- if current_user
@@ -48,7 +46,8 @@
%a.navbar-link{:href => tenant_user_path(current_user.current_tenant, current_user)}
= current_user
- %li
- %a.navbar-link{:href => log_out_path}
- %i.icon-off.icon-white
+ - if single_sign_on_system? == false
+ %li
+ %a.navbar-link{:href => log_out_path}
+ %i.icon-off.icon-white
diff --git a/app/views/phone_numbers/_form_core.html.haml b/app/views/phone_numbers/_form_core.html.haml
index a1ce1f3..a0a69db 100644
--- a/app/views/phone_numbers/_form_core.html.haml
+++ b/app/views/phone_numbers/_form_core.html.haml
@@ -4,7 +4,7 @@
= f.input :name, :collection => ['Office', 'Home', 'Mobile', 'Fax'], :include_blank => false, :label => t('phone_numbers.form.name.label'), :hint => conditional_hint('phone_numbers.form.name.hint')
= f.input :number, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint'), :autofocus => true
- else
- - if @callthrough || @hunt_group_member || @access_authorization || @current_user.current_tenant.array_of_available_internal_extensions_and_dids.count == 0 || @current_user.current_tenant.array_of_available_internal_extensions_and_dids.count > 250
+ - if @callthrough || @hunt_group_member || @access_authorization || current_user.current_tenant.array_of_available_internal_extensions_and_dids.count == 0 || current_user.current_tenant.array_of_available_internal_extensions_and_dids.count > 250
= f.input :number, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint'), :autofocus => true
- else
- = f.input :number, :collection => @current_user.current_tenant.array_of_available_internal_extensions_and_dids, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint'), :include_blank => false, :autofocus => true
+ = f.input :number, :collection => current_user.current_tenant.array_of_available_internal_extensions_and_dids, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint'), :include_blank => false, :autofocus => true
diff --git a/app/views/phone_numbers/_index_core.html.haml b/app/views/phone_numbers/_index_core.html.haml
index 80a1608..85982da 100644
--- a/app/views/phone_numbers/_index_core.html.haml
+++ b/app/views/phone_numbers/_index_core.html.haml
@@ -1,13 +1,18 @@
%table.table.table-striped
%thead
%tr
+ %th
- if phone_numbers.count > 1 && phone_numbers.first.phone_numberable_type == 'PhoneBookEntry'
%th= t('phone_numbers.index.name')
%th= t('phone_numbers.index.number')
- %tbody
+ %tbody{ :id => "phone_numbers", :'data-update-url' => sort_phone_numbers_url}
- for phone_number in phone_numbers.order(:position)
- %tr
+ = content_tag_for :tr, phone_number do
+ %td
+ - if phone_numbers.count > 1
+ %span.handle
+ %i.icon-resize-vertical
- if phone_number.phone_numberable_type == 'PhoneBookEntry'
%td= phone_number.name
%td= phone_number
diff --git a/app/views/phones/_form_core.html.haml b/app/views/phones/_form_core.html.haml
index 17b9ca8..31f3c24 100644
--- a/app/views/phones/_form_core.html.haml
+++ b/app/views/phones/_form_core.html.haml
@@ -11,5 +11,5 @@
- if defined? GsParameter.get('NIGHTLY_REBOOT_OF_PHONES') && GsParameter.get('NIGHTLY_REBOOT_OF_PHONES') == true
= f.input :nightly_reboot, :label => t('phones.form.nightly_reboot.label'), :hint => conditional_hint('phones.form.nightly_reboot.hint')
- - if !GsParameter.get('PROVISIONING_KEY_LENGTH').nil? && GsParameter.get('PROVISIONING_KEY_LENGTH') > 0
+ - if GsParameter.get('PROVISIONING_KEY_LENGTH') == 0
= f.input :provisioning_key_active, :label => t('phones.form.provisioning_key_active.label'), :hint => conditional_hint('phones.form.provisioning_key_active.hint')
diff --git a/app/views/phones/show.html.haml b/app/views/phones/show.html.haml
index 86ac380..e9b8b21 100644
--- a/app/views/phones/show.html.haml
+++ b/app/views/phones/show.html.haml
@@ -34,7 +34,7 @@
%td
= @phone.nightly_reboot == true ? t('simple_form.yes') : t('simple_form.no')
- - if !GsParameter.get('PROVISIONING_KEY_LENGTH').nil? && GsParameter.get('PROVISIONING_KEY_LENGTH') > 0
+ - if GsParameter.get('PROVISIONING_KEY_LENGTH') == 0
%tr
%td
%strong= t('phones.show.provisioning_key_active') + ":"
diff --git a/app/views/route_elements/_index_core.html.haml b/app/views/route_elements/_index_core.html.haml
index 37c0656..b7d2bc1 100644
--- a/app/views/route_elements/_index_core.html.haml
+++ b/app/views/route_elements/_index_core.html.haml
@@ -1,20 +1,46 @@
%table.table.table-striped
%thead
%tr
- %th= t('route_elements.index.var_in')
- %th= t('route_elements.index.var_out')
+ - if route_elements.count > 1
+ %th
+ %th
+ %span.hidden-phone
+ = t('route_elements.index.var_in')
+ %th
+ %span.hidden-phone
+ = t('route_elements.index.var_out')
%th= t('route_elements.index.pattern')
- %th= t('route_elements.index.replacement')
- %th= t('route_elements.index.action')
- %th= t('route_elements.index.mandatory')
+ %th
+ %span.hidden-phone
+ = t('route_elements.index.replacement')
+ %th
+ %span.hidden-phone
+ = t('route_elements.index.action')
+ %th
+ %span.hidden-phone
+ = t('route_elements.index.mandatory')
- %tbody
+ %tbody{ :id => "route_elements", :'data-update-url' => sort_call_route_route_elements_url(route_elements.first.call_route)}
- for route_element in route_elements
- %tr
- %td= route_element.var_in
- %td= route_element.var_out
+ = content_tag_for :tr, route_element do
+ - if route_elements.count > 1
+ %td
+ %span.handle
+ %i.icon-resize-vertical
+ %td
+ %span.hidden-phone
+ = route_element.var_in
+ %td
+ %span.hidden-phone
+ = route_element.var_out
%td= route_element.pattern
- %td= route_element.replacement
- %td= route_element.action
- %td= route_element.mandatory
+ %td
+ %span.hidden-phone
+ = route_element.replacement
+ %td
+ %span.hidden-phone
+ = route_element.action
+ %td
+ %span.hidden-phone
+ = route_element.mandatory
=render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => @call_route, :child => route_element} \ No newline at end of file
diff --git a/app/views/route_elements/show.html.haml b/app/views/route_elements/show.html.haml
index 808f2a0..937df5e 100644
--- a/app/views/route_elements/show.html.haml
+++ b/app/views/route_elements/show.html.haml
@@ -1,22 +1,37 @@
- content_for :title, t("route_elements.show.page_title")
-%p
- %strong= t('route_elements.show.var_in') + ":"
- = @route_element.var_in
-%p
- %strong= t('route_elements.show.var_out') + ":"
- = @route_element.var_out
-%p
- %strong= t('route_elements.show.pattern') + ":"
- = @route_element.pattern
-%p
- %strong= t('route_elements.show.replacement') + ":"
- = @route_element.replacement
-%p
- %strong= t('route_elements.show.action') + ":"
- = @route_element.action
-%p
- %strong= t('route_elements.show.mandatory') + ":"
- = @route_element.mandatory
+.row
+ .span6
+ %table.table.table-striped
+ %tr
+ %td
+ %strong= t('route_elements.show.var_in') + ":"
+ %td
+ = @route_element.var_in
+ %tr
+ %td
+ %strong= t('route_elements.show.var_out') + ":"
+ %td
+ = @route_element.var_out
+ %tr
+ %td
+ %strong= t('route_elements.show.pattern') + ":"
+ %td
+ = @route_element.pattern
+ %tr
+ %td
+ %strong= t('route_elements.show.replacement') + ":"
+ %td
+ = @route_element.replacement
+ %tr
+ %td
+ %strong= t('route_elements.show.action') + ":"
+ %td
+ = @route_element.action
+ %tr
+ %td
+ %strong= t('route_elements.show.mandatory') + ":"
+ %td
+ = @route_element.mandatory
= render :partial => 'shared/show_edit_destroy_part', :locals => {:parent => @call_route, :child => @route_element } \ No newline at end of file
diff --git a/app/views/shared/_index_view_edit_destroy_part.html.haml b/app/views/shared/_index_view_edit_destroy_part.html.haml
index 6bb1e7b..d396460 100644
--- a/app/views/shared/_index_view_edit_destroy_part.html.haml
+++ b/app/views/shared/_index_view_edit_destroy_part.html.haml
@@ -4,17 +4,20 @@
- if can? :show, child
%a.btn.btn-small.btn-success{:href => method( :"#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child) }
%i.icon-info-sign.icon-white
- =t("#{child.class.name.underscore.pluralize}.index.actions.show")
+ %span.hidden-phone
+ =t("#{child.class.name.underscore.pluralize}.index.actions.show")
- if can? :edit, child
%a.btn.btn-small.btn-warning{:href => method( :"edit_#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child) }
%i.icon-edit.icon-white
- =t("#{child.class.name.underscore.pluralize}.index.actions.edit")
+ %span.hidden-phone
+ =t("#{child.class.name.underscore.pluralize}.index.actions.edit")
- if can? :destroy, child
%a.btn.btn-small.btn-danger{"data-confirm" => t("#{child.class.name.underscore.pluralize}.index.actions.confirm_destroy"), "data-method" => "delete", :href => method( :"#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child), :rel => "nofollow"}
%i.icon-remove.icon-white
- =t("#{child.class.name.underscore.pluralize}.index.actions.destroy")
+ %span.hidden-phone
+ =t("#{child.class.name.underscore.pluralize}.index.actions.destroy")
- elsif !(defined? child).nil?
%td
@@ -22,15 +25,18 @@
- if can? :show, child
%a.btn.btn-small.btn-success{:href => method( :"#{child.class.name.underscore}_path" ).(child) }
%i.icon-info-sign.icon-white
- =t("#{child.class.name.underscore.pluralize}.index.actions.show")
+ %span.hidden-phone
+ =t("#{child.class.name.underscore.pluralize}.index.actions.show")
- if can? :edit, child
%a.btn.btn-small.btn-warning{:href => method( :"edit_#{child.class.name.underscore}_path" ).(child) }
%i.icon-edit.icon-white
- =t("#{child.class.name.underscore.pluralize}.index.actions.edit")
+ %span.hidden-phone
+ =t("#{child.class.name.underscore.pluralize}.index.actions.edit")
- if can? :destroy, child
%a.btn.btn-small.btn-danger{"data-confirm" => t("#{child.class.name.underscore.pluralize}.index.actions.confirm_destroy"), "data-method" => "delete", :href => method( :"#{child.class.name.underscore}_path" ).(child), :rel => "nofollow"}
%i.icon-trash.icon-white
- =t("#{child.class.name.underscore.pluralize}.index.actions.destroy")
+ %span.hidden-phone
+ =t("#{child.class.name.underscore.pluralize}.index.actions.destroy")
\ No newline at end of file
diff --git a/app/views/softkeys/_form_core.html.haml b/app/views/softkeys/_form_core.html.haml
index b833aad..2863d5c 100644
--- a/app/views/softkeys/_form_core.html.haml
+++ b/app/views/softkeys/_form_core.html.haml
@@ -7,6 +7,6 @@
.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
- if @available_call_forwards && @available_call_forwards.count > 0
- = f.association :call_forward, :collection => @available_call_forwards, :label => t('softkeys.form.call_forward.label'), :hint => conditional_hint('softkeys.form.call_forward.hint'), :include_blank => false
+ = f.association :softkeyable, :collection => @available_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/app/views/softkeys/_index_core.html.haml b/app/views/softkeys/_index_core.html.haml
index 398ee51..4a06c72 100644
--- a/app/views/softkeys/_index_core.html.haml
+++ b/app/views/softkeys/_index_core.html.haml
@@ -1,15 +1,21 @@
-%table.table.table-striped
- %thead
- %tr
- %th= t('softkeys.index.function')
- %th= t('softkeys.index.number')
- %th= t('softkeys.index.label')
-
- %tbody
- - for softkey in softkeys.order(:position)
+- cache(['softkeys_table', I18n.locale, current_user, softkeys]) do
+ %table.table.table-striped
+ %thead
%tr
- %td
- =softkey.to_s
- %td= softkey.number
- %td= softkey.label
- =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => softkey.sip_account, :child => softkey} \ No newline at end of file
+ %th
+ %th= t('softkeys.index.function')
+ %th= t('softkeys.index.number')
+ %th= t('softkeys.index.label')
+
+ %tbody{ :id => "softkeys", :'data-update-url' => sort_softkeys_url}
+ - for softkey in softkeys
+ - cache(['softkeys_table_tr', I18n.locale, current_user, softkey]) do
+ = content_tag_for :tr, softkey do
+ %td
+ - if softkeys.count > 1
+ %span.handle
+ %i.icon-resize-vertical
+ %td= t("softkeys.functions.#{softkey.softkey_function}")
+ %td= softkey.number
+ %td= softkey.label
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => softkey.sip_account, :child => softkey} \ No newline at end of file
diff --git a/app/views/softkeys/show.html.haml b/app/views/softkeys/show.html.haml
index d0db111..7c068ae 100644
--- a/app/views/softkeys/show.html.haml
+++ b/app/views/softkeys/show.html.haml
@@ -1,7 +1,7 @@
- content_for :title, t("softkeys.show.page_title")
%p
- %strong= t('softkeys.show.function') + ":"
+ %strong= t("softkeys.functions.#{@softkey.softkey_function}") + ":"
=@softkey.to_s
-= render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @softkey.sip_account, :child => @softkey } \ No newline at end of file
+= render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @softkey.sip_account, :child => @softkey }
diff --git a/app/views/system_messages/_form.html.haml b/app/views/system_messages/_form.html.haml
deleted file mode 100644
index 036ee00..0000000
--- a/app/views/system_messages/_form.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-= simple_form_for([@user, @system_message]) do |f|
- = f.error_notification
-
- = render "form_core", :f => f
-
- .actions
- = f.button :submit, conditional_t('system_messages.form.submit') \ No newline at end of file
diff --git a/app/views/system_messages/_form_core.html.haml b/app/views/system_messages/_form_core.html.haml
deleted file mode 100644
index a85db28..0000000
--- a/app/views/system_messages/_form_core.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-.inputs
- = f.input :content, :label => t('system_messages.form.content.label'), :hint => conditional_hint('system_messages.form.content.hint')
diff --git a/app/views/system_messages/_index_core.html.haml b/app/views/system_messages/_index_core.html.haml
deleted file mode 100644
index 7c9dab5..0000000
--- a/app/views/system_messages/_index_core.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-%table.table.table-striped
- %thead
- %tr
- %th= t('system_messages.index.created_at')
- %th= t('system_messages.index.content')
-
- %tbody
- - for system_message in system_messages
- %tr
- %td= system_message.created_at
- %td= system_message.content
- =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => system_message} \ No newline at end of file
diff --git a/app/views/system_messages/index.html.haml b/app/views/system_messages/index.html.haml
deleted file mode 100644
index ffd3fc3..0000000
--- a/app/views/system_messages/index.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-- content_for :title, t("system_messages.index.page_title")
-
-= render "index_core", :system_messages => @system_messages \ No newline at end of file
diff --git a/app/views/system_messages/new.html.haml b/app/views/system_messages/new.html.haml
deleted file mode 100644
index 565f5c5..0000000
--- a/app/views/system_messages/new.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-- content_for :title, t("system_messages.new.page_title")
-
-= render "form"
diff --git a/app/views/system_messages/show.html.haml b/app/views/system_messages/show.html.haml
deleted file mode 100644
index 70be6f2..0000000
--- a/app/views/system_messages/show.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-- content_for :title, t("system_messages.show.page_title")
-
-%p
- %strong= t('system_messages.show.created_at') + ":"
- = @system_message.created_at
-%p
- %strong= t('system_messages.show.content') + ":"
- = @system_message.content
diff --git a/app/views/tenants/_admin_area.html.haml b/app/views/tenants/_admin_area.de.html.haml
index 28a8273..2aed4e1 100644
--- a/app/views/tenants/_admin_area.html.haml
+++ b/app/views/tenants/_admin_area.de.html.haml
@@ -23,7 +23,7 @@
%p
Das System kann
= PhoneModel.count
- verschiedene Telefonmodelle von den folgenden Herstellern verwalten:
+ verschiedene Telefonmodelle von den folgenden Herstellern automatisch provisionieren:
- Manufacturer.all.each do |manufacturer|
- if manufacturer != Manufacturer.last && manufacturer != Manufacturer.limit(Manufacturer.count - 1).last
= succeed ', ' do
@@ -37,4 +37,6 @@
= render :partial => 'call_routes', :locals => {:tenant => tenant}
- = render :partial => 'gateways', :locals => {:tenant => tenant, :gateways => gateways} \ No newline at end of file
+ = render :partial => 'gateways', :locals => {:tenant => tenant, :gateways => gateways}
+
+ = render :partial => 'table_of_backup_jobs', :locals => {:tenant => tenant, :backup_jobs => backup_jobs}
diff --git a/app/views/tenants/_admin_area.en.html.haml b/app/views/tenants/_admin_area.en.html.haml
new file mode 100644
index 0000000..8e7bfea
--- /dev/null
+++ b/app/views/tenants/_admin_area.en.html.haml
@@ -0,0 +1,42 @@
+
+.row
+ .span12
+ = render :partial => 'tenants/table_of_sip_accounts', :locals => {:tenant => tenant}
+ - if SipAccount.any?
+ = render :partial => 'tenants/table_of_phones', :locals => {:tenant => tenant}
+
+ - if SipAccount.any? || Gateway.any?
+ = render :partial => 'tenants/table_of_conferences', :locals => {:tenant => tenant}
+ = render :partial => 'tenants/table_of_callthroughs', :locals => {:tenant => tenant}
+ = render :partial => 'tenants/table_of_hunt_groups', :locals => {:tenant => tenant}
+ = render :partial => 'tenants/table_of_automatic_call_distributors', :locals => {:tenant => tenant}
+
+ = render :partial => 'tenants/users_table', :locals => {:tenant => tenant}
+ = render :partial => 'tenants/user_groups_table', :locals => {:tenant => tenant}
+
+ = render :partial => 'tenants/table_of_phone_books', :locals => {:tenant => tenant}
+
+ .well
+ %h2 Gemeinschaft Configuration
+ = render :partial => 'tenants/gs_parameter_table', :locals => {:tenant => tenant}
+
+ %p
+ This system can provision a total of
+ = PhoneModel.count
+ different phone models of the following manufacturers:
+ - Manufacturer.all.each do |manufacturer|
+ - if manufacturer != Manufacturer.last && manufacturer != Manufacturer.limit(Manufacturer.count - 1).last
+ = succeed ', ' do
+ =link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + manufacturer, manufacturer_path(manufacturer)
+ - elsif manufacturer == Manufacturer.limit(Manufacturer.count - 1).last
+ = succeed ' and ' do
+ =link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + manufacturer, manufacturer_path(manufacturer)
+ - else
+ = succeed '.' do
+ =link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + manufacturer, manufacturer_path(manufacturer)
+
+ = render :partial => 'call_routes', :locals => {:tenant => tenant}
+
+ = render :partial => 'gateways', :locals => {:tenant => tenant, :gateways => gateways}
+
+ = render :partial => 'table_of_backup_jobs', :locals => {:tenant => tenant, :backup_jobs => backup_jobs} \ No newline at end of file
diff --git a/app/views/tenants/_table_of_backup_jobs.html.haml b/app/views/tenants/_table_of_backup_jobs.html.haml
new file mode 100644
index 0000000..a585010
--- /dev/null
+++ b/app/views/tenants/_table_of_backup_jobs.html.haml
@@ -0,0 +1,11 @@
+-# BackupJobs
+-#
+- if (can?( :index, BackupJob ) && backup_jobs.count > 0 ) || can?( :create, BackupJob )
+ - if backup_jobs.count == BackupJob.count
+ %h2= t('backup_jobs.index.page_title')
+ - else
+ %h2= t('backup_jobs.index.page_title_with_limit', :limit => '5')
+
+ - if can?( :index, BackupJob ) && backup_jobs.count > 0
+ = render "backup_jobs/index_core", :backup_jobs => backup_jobs
+ = render :partial => 'shared/create_link', :locals => {:child_class => BackupJob} \ No newline at end of file
diff --git a/app/views/tenants/show.html.haml b/app/views/tenants/show.html.haml
index 818e584..23ec81a 100644
--- a/app/views/tenants/show.html.haml
+++ b/app/views/tenants/show.html.haml
@@ -15,4 +15,4 @@
= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @tenant }
- if @tenant.user_groups.where(:name => 'Admins').any? && @tenant.user_groups.where(:name => 'Admins').first.users.include?(current_user)
- = render :partial => 'admin_area', :locals => { :tenant => @tenant, :gateways => @gateways} \ No newline at end of file
+ = render :partial => 'admin_area', :locals => { :tenant => @tenant, :gateways => @gateways, :backup_jobs => @backup_jobs} \ No newline at end of file
diff --git a/config/backup.rb b/config/backup.rb
new file mode 100644
index 0000000..e5816c1
--- /dev/null
+++ b/config/backup.rb
@@ -0,0 +1,60 @@
+# encoding: utf-8
+
+require 'inifile'
+SYSTEM_ODBC_CONFIGURATION = IniFile.load('/var/lib/freeswitch/.odbc.ini')
+
+Backup::Model.new(:GS5, 'GS5 backup') do
+
+ ##
+ # Split [Splitter]
+ #
+ # Split the backup file in to chunks of 2 GB
+ # if the backup file size exceeds 2 GB
+ #
+ # split_into_chunks_of 2048
+
+ ##
+ # MySQL [Database]
+ #
+ database MySQL do |db|
+ # To dump all databases, set `db.name = :all` (or leave blank)
+ db.name = SYSTEM_ODBC_CONFIGURATION['gemeinschaft']['DATABASE']
+ db.username = SYSTEM_ODBC_CONFIGURATION['gemeinschaft']['USER']
+ db.password = SYSTEM_ODBC_CONFIGURATION['gemeinschaft']['PASSWORD']
+ db.host = "localhost"
+ db.port = 3306
+ db.socket = "/var/run/mysqld/mysqld.sock"
+ end
+
+ ##
+ # Faxes
+ #
+ if File.exists?('/opt/gemeinschaft/public/uploads/fax_document')
+ archive :faxes do |archive|
+ archive.add '/opt/gemeinschaft/public/uploads/fax_document'
+ end
+ end
+
+ ##
+ # Voicemails
+ #
+ if File.exists?('/var/opt/gemeinschaft/freeswitch/voicemail')
+ archive :voicemails do |archive|
+ archive.add '/var/opt/gemeinschaft/freeswitch/voicemail'
+ end
+ end
+
+ ##
+ # Local (Copy) [Storage]
+ #
+ store_with Local do |local|
+ local.path = "/var/backups/"
+ end
+
+ ##
+ # Gzip [Compressor]
+ #
+ compress_with Gzip
+
+end
+
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 9d85d8e..ffc8e69 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -192,7 +192,7 @@ de:
formats:
default: ! '%A, %d. %B %Y, %H:%M Uhr'
long: ! '%A, %d. %B %Y, %H:%M Uhr'
- short: ! '%d. %B, %H:%M Uhr'
+ short: ! '%d.%m.%Y %H:%M Uhr'
pm: nachmittags
date_only: '%d.%m.%Y'
misc:
diff --git a/config/locales/navigation.de.yml b/config/locales/navigation.de.yml
new file mode 100644
index 0000000..779248c
--- /dev/null
+++ b/config/locales/navigation.de.yml
@@ -0,0 +1,3 @@
+de:
+ navigation:
+ admin_docu: 'Admin-Doku' \ No newline at end of file
diff --git a/config/locales/navigation.en.yml b/config/locales/navigation.en.yml
new file mode 100644
index 0000000..82e901b
--- /dev/null
+++ b/config/locales/navigation.en.yml
@@ -0,0 +1,3 @@
+en:
+ navigation:
+ admin_docu: 'Admin-Docu' \ No newline at end of file
diff --git a/config/locales/views/backup_jobs/de.yml b/config/locales/views/backup_jobs/de.yml
new file mode 100644
index 0000000..8e23feb
--- /dev/null
+++ b/config/locales/views/backup_jobs/de.yml
@@ -0,0 +1,61 @@
+de:
+ backup_jobs:
+ name: 'Backup-Auftrag'
+ controller:
+ successfuly_created: 'Backup-Auftrag wurde angelegt.'
+ successfuly_updated: 'Backup-Auftrag wurde aktualisiert.'
+ successfuly_destroyed: 'Backup-Auftrag wurde gelöscht.'
+ index:
+ page_title: 'Liste aller Backup-Aufträge'
+ page_title_with_limit: 'Liste der letzten %{limit} Backup-Aufträge'
+ started_at: 'Start'
+ finished_at: 'Ende'
+ state: 'Status'
+ directory: 'Verzeichnis'
+ size_of_the_backup: 'Größe'
+ actions:
+ confirm_destroy: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Backup-Auftrag'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Backup-Auftrag neu anlegen für %{resource}'
+ show:
+ page_title: 'Backup-Auftrag bearbeiten'
+ started_at: 'Start'
+ finished_at: 'Ende'
+ state: 'Status'
+ directory: 'Verzeichnis'
+ size_of_the_backup: 'Größe'
+ actions:
+ confirm_destroy: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Backup-Auftrag neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Backup-Auftrag bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ started_at:
+ label: 'Start'
+ hint: ''
+ finished_at:
+ label: 'Ende'
+ hint: ''
+ state:
+ label: 'Status'
+ hint: ''
+ directory:
+ label: 'Verzeichnis'
+ hint: ''
+ size_of_the_backup:
+ label: 'Größe'
+ hint: ''
+ submit: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/backup_jobs/en.yml b/config/locales/views/backup_jobs/en.yml
new file mode 100644
index 0000000..74d14c2
--- /dev/null
+++ b/config/locales/views/backup_jobs/en.yml
@@ -0,0 +1,61 @@
+en:
+ backup_jobs:
+ name: 'Backup job'
+ controller:
+ successfuly_created: 'Successfully created backup job.'
+ successfuly_updated: 'Successfully updated backup job.'
+ successfuly_destroyed: 'Successfully destroyed backup job.'
+ index:
+ page_title: 'Listing backup jobs'
+ page_title_with_limit: 'Listing of the last %{limit} backup jobs'
+ started_at: 'Started at'
+ finished_at: 'Finished at'
+ state: 'State'
+ directory: 'Directory'
+ size_of_the_backup: 'Size of the backup'
+ actions:
+ confirm_destroy: 'Are you sure you want to delete this backup job?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New backup job for %{resource}'
+ show:
+ page_title: 'Show backup job'
+ started_at: 'Started at'
+ finished_at: 'Finished at'
+ state: 'State'
+ directory: 'Directory'
+ size_of_the_backup: 'Size of the backup'
+ actions:
+ confirm_destroy: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ new:
+ page_title: 'New backup job'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing backup job'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ started_at:
+ label: 'Started at'
+ hint: ''
+ finished_at:
+ label: 'Finished at'
+ hint: ''
+ state:
+ label: 'State'
+ hint: ''
+ directory:
+ label: 'Directory'
+ hint: ''
+ size_of_the_backup:
+ label: 'Size of the backup'
+ hint: ''
+ submit: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/call_routes/de.yml b/config/locales/views/call_routes/de.yml
index a8d6f4b..c9df1c2 100644
--- a/config/locales/views/call_routes/de.yml
+++ b/config/locales/views/call_routes/de.yml
@@ -1,25 +1,25 @@
de:
call_routes:
- name: 'Call Route'
+ name: 'Call-Route'
controller:
- successfuly_created: 'Call Route wurde angelegt.'
- successfuly_updated: 'Call Route wurde aktualisiert.'
- successfuly_destroyed: 'Call Route wurde gelöscht.'
+ successfuly_created: 'Call-Route wurde angelegt.'
+ successfuly_updated: 'Call-Route wurde aktualisiert.'
+ successfuly_destroyed: 'Call-Route wurde gelöscht.'
index:
- page_title: 'Liste aller Call Routen'
- routing_table: 'Routing Table'
+ page_title: 'Liste Call-Routen'
+ routing_table: 'Routing Tabelle'
name: 'Name'
- endpoint: 'Endpoint'
+ endpoint: 'Endpunkt'
position: 'Position'
actions:
- confirm_destroy: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Call Route'
+ confirm_destroy: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Call-Route'
destroy: 'Löschen'
edit: 'Bearbeiten'
show: 'Anzeigen'
create: 'Neu anlegen'
- create_for: 'Call Route neu anlegen für %{resource}'
+ create_for: 'Call-Route neu anlegen für %{resource}'
show:
- page_title: 'Call Route bearbeiten'
+ page_title: 'Call-Route bearbeiten'
routing_table: 'Routing Table'
name: 'Name'
endpoint: 'Endpoint'
@@ -30,11 +30,11 @@ de:
edit: 'Bearbeiten'
view_all: 'Alle anzeigen'
new:
- page_title: 'Call Route neu anlegen'
+ page_title: 'Call-Route neu anlegen'
actions:
back_to_list: 'Zurück zur Übersicht'
edit:
- page_title: 'Call Route bearbeiten'
+ page_title: 'Call-Route bearbeiten'
actions:
back_to_list: 'Zurück zur Übersicht'
edit: 'Bearbeiten'
@@ -46,10 +46,7 @@ de:
name:
label: 'Name'
hint: ''
- endpoint_type:
- label: 'Endpoint type'
- hint: ''
- endpoint_id:
+ endpoint:
label: 'Endpoint'
hint: ''
position:
diff --git a/config/locales/views/call_routes/en.yml b/config/locales/views/call_routes/en.yml
index 8596474..c37773d 100644
--- a/config/locales/views/call_routes/en.yml
+++ b/config/locales/views/call_routes/en.yml
@@ -46,10 +46,7 @@ en:
name:
label: 'Name'
hint: ''
- endpoint_type:
- label: 'Endpoint type'
- hint: ''
- endpoint_id:
+ endpoint:
label: 'Endpoint'
hint: ''
position:
diff --git a/config/locales/views/gemeinschaft_setups/de.yml b/config/locales/views/gemeinschaft_setups/de.yml
index 57bc7e6..eb0145c 100644
--- a/config/locales/views/gemeinschaft_setups/de.yml
+++ b/config/locales/views/gemeinschaft_setups/de.yml
@@ -28,6 +28,9 @@ de:
default_area_code:
label: 'Standard Ortsvorwahl'
hint: '030 für Berlin, 0261 für Koblenz, 02631 für Neuwied, usw.'
+ trunk_access_code:
+ label: 'Amtsholungsziffer'
+ hint: ''
default_company_name:
label: 'Name der Organisation'
hint: 'z.B. Firmenname'
diff --git a/config/locales/views/gemeinschaft_setups/en.yml b/config/locales/views/gemeinschaft_setups/en.yml
index 9d5f965..3a1ac39 100644
--- a/config/locales/views/gemeinschaft_setups/en.yml
+++ b/config/locales/views/gemeinschaft_setups/en.yml
@@ -28,6 +28,9 @@ en:
default_area_code:
label: 'Default area code'
hint: ''
+ trunk_access_code:
+ label: 'Trunk access code'
+ hint: ''
default_company_name:
label: 'Name of the organisation'
hint: 'e.g. name of the company'
diff --git a/config/locales/views/intruders/de.yml b/config/locales/views/intruders/de.yml
new file mode 100644
index 0000000..42ece4b
--- /dev/null
+++ b/config/locales/views/intruders/de.yml
@@ -0,0 +1,110 @@
+de:
+ intruders:
+ name: 'Intruder'
+ controller:
+ successfuly_created: 'Intruder wurde angelegt.'
+ successfuly_updated: 'Intruder wurde aktualisiert.'
+ successfuly_destroyed: 'Intruder wurde gelöscht.'
+ index:
+ page_title: 'Ãœbersicht von Intruder'
+ list_type: 'List type'
+ key: 'Key'
+ points: 'Points'
+ bans: 'Bans'
+ ban_last: 'Ban last'
+ ban_end: 'Ban end'
+ contact_ip: 'Contact ip'
+ contact_port: 'Contact port'
+ contact_count: 'Contact count'
+ contact_last: 'Contact last'
+ contacts_per_second: 'Contacts per second'
+ contacts_per_second_max: 'Contacts per second max'
+ user_agent: 'User agent'
+ to_user: 'To user'
+ comment: 'Comment'
+ actions:
+ confirm_destroy: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Intruder'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Intruder neu anlegen für %{resource}'
+ show:
+ page_title: 'Intruder bearbeiten'
+ list_type: 'List type'
+ key: 'Key'
+ points: 'Points'
+ bans: 'Bans'
+ ban_last: 'Ban last'
+ ban_end: 'Ban end'
+ contact_ip: 'Contact ip'
+ contact_port: 'Contact port'
+ contact_count: 'Contact count'
+ contact_last: 'Contact last'
+ contacts_per_second: 'Contacts per second'
+ contacts_per_second_max: 'Contacts per second max'
+ user_agent: 'User agent'
+ to_user: 'To user'
+ comment: 'Comment'
+ actions:
+ confirm_destroy: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Intruder neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Intruder bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ list_type:
+ label: 'List type'
+ hint: ''
+ key:
+ label: 'Key'
+ hint: ''
+ points:
+ label: 'Points'
+ hint: ''
+ bans:
+ label: 'Bans'
+ hint: ''
+ ban_last:
+ label: 'Ban last'
+ hint: ''
+ ban_end:
+ label: 'Ban end'
+ hint: ''
+ contact_ip:
+ label: 'Contact ip'
+ hint: ''
+ contact_port:
+ label: 'Contact port'
+ hint: ''
+ contact_count:
+ label: 'Contact count'
+ hint: ''
+ contact_last:
+ label: 'Contact last'
+ hint: ''
+ contacts_per_second:
+ label: 'Contacts per second'
+ hint: ''
+ contacts_per_second_max:
+ label: 'Contacts per second max'
+ hint: ''
+ user_agent:
+ label: 'User agent'
+ hint: ''
+ to_user:
+ label: 'To user'
+ hint: ''
+ comment:
+ label: 'Comment'
+ hint: ''
+ submit: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/intruders/en.yml b/config/locales/views/intruders/en.yml
new file mode 100644
index 0000000..99c2dcb
--- /dev/null
+++ b/config/locales/views/intruders/en.yml
@@ -0,0 +1,110 @@
+en:
+ intruders:
+ name: 'Intruder'
+ controller:
+ successfuly_created: 'Successfully created Intruder.'
+ successfuly_updated: 'Successfully updated Intruder.'
+ successfuly_destroyed: 'Successfully destroyed Intruder.'
+ index:
+ page_title: 'Listing Intruder'
+ list_type: 'List type'
+ key: 'Key'
+ points: 'Points'
+ bans: 'Bans'
+ ban_last: 'Ban last'
+ ban_end: 'Ban end'
+ contact_ip: 'Contact ip'
+ contact_port: 'Contact port'
+ contact_count: 'Contact count'
+ contact_last: 'Contact last'
+ contacts_per_second: 'Contacts per second'
+ contacts_per_second_max: 'Contacts per second max'
+ user_agent: 'User agent'
+ to_user: 'To user'
+ comment: 'Comment'
+ actions:
+ confirm_destroy: 'Are you sure you want to delete this Intruder?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New Intruder for %{resource}'
+ show:
+ page_title: 'Show Intruder'
+ list_type: 'List type'
+ key: 'Key'
+ points: 'Points'
+ bans: 'Bans'
+ ban_last: 'Ban last'
+ ban_end: 'Ban end'
+ contact_ip: 'Contact ip'
+ contact_port: 'Contact port'
+ contact_count: 'Contact count'
+ contact_last: 'Contact last'
+ contacts_per_second: 'Contacts per second'
+ contacts_per_second_max: 'Contacts per second max'
+ user_agent: 'User agent'
+ to_user: 'To user'
+ comment: 'Comment'
+ actions:
+ confirm_destroy: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ new:
+ page_title: 'New Intruder'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing Intruder'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ list_type:
+ label: 'List type'
+ hint: ''
+ key:
+ label: 'Key'
+ hint: ''
+ points:
+ label: 'Points'
+ hint: ''
+ bans:
+ label: 'Bans'
+ hint: ''
+ ban_last:
+ label: 'Ban last'
+ hint: ''
+ ban_end:
+ label: 'Ban end'
+ hint: ''
+ contact_ip:
+ label: 'Contact ip'
+ hint: ''
+ contact_port:
+ label: 'Contact port'
+ hint: ''
+ contact_count:
+ label: 'Contact count'
+ hint: ''
+ contact_last:
+ label: 'Contact last'
+ hint: ''
+ contacts_per_second:
+ label: 'Contacts per second'
+ hint: ''
+ contacts_per_second_max:
+ label: 'Contacts per second max'
+ hint: ''
+ user_agent:
+ label: 'User agent'
+ hint: ''
+ to_user:
+ label: 'To user'
+ hint: ''
+ comment:
+ label: 'Comment'
+ hint: ''
+ submit: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/phones/de.yml b/config/locales/views/phones/de.yml
index 373db13..02875c4 100644
--- a/config/locales/views/phones/de.yml
+++ b/config/locales/views/phones/de.yml
@@ -9,9 +9,9 @@ de:
page_title: 'Telefone'
mac_address: 'MAC-Adresse'
phone_model_id: 'Modell'
- hot_deskable: 'Hot-Desk fähig'
- ip_address: 'IP-Adresse'
- last_ip_address: 'Letzte IP-Adresse'
+ hot_deskable: 'Hot-Desk'
+ ip_address: 'IP'
+ last_ip_address: 'Letzte IP'
http_user: 'Phone WebGUI Username'
http_password: 'Phone WebGUI Passwort'
nightly_reboot: 'Nachts automatischer Reboot'
diff --git a/config/locales/views/route_elements/de.yml b/config/locales/views/route_elements/de.yml
index fe14671..70a6162 100644
--- a/config/locales/views/route_elements/de.yml
+++ b/config/locales/views/route_elements/de.yml
@@ -1,12 +1,12 @@
de:
route_elements:
- name: 'Route element'
+ name: 'Routen-Element'
controller:
- successfuly_created: 'Route element wurde angelegt.'
- successfuly_updated: 'Route element wurde aktualisiert.'
- successfuly_destroyed: 'Route element wurde gelöscht.'
+ successfuly_created: 'Routen-Element wurde angelegt.'
+ successfuly_updated: 'Routen-Element wurde aktualisiert.'
+ successfuly_destroyed: 'Routen-Element wurde gelöscht.'
index:
- page_title: 'Ãœbersicht von Route element'
+ page_title: 'Liste Routen-Elemente'
call_route_id: 'Call route'
var_in: 'Var in'
var_out: 'Var out'
@@ -16,14 +16,14 @@ de:
mandatory: 'Mandatory'
position: 'Position'
actions:
- confirm_destroy: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Route element'
+ confirm_destroy: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Routen-Element'
destroy: 'Löschen'
edit: 'Bearbeiten'
show: 'Anzeigen'
create: 'Neu anlegen'
- create_for: 'Route element neu anlegen für %{resource}'
+ create_for: 'Routen-Element neu anlegen für %{resource}'
show:
- page_title: 'Route element bearbeiten'
+ page_title: 'Routen-Element bearbeiten'
call_route_id: 'Call route'
var_in: 'Var in'
var_out: 'Var out'
@@ -38,11 +38,11 @@ de:
edit: 'Bearbeiten'
view_all: 'Alle anzeigen'
new:
- page_title: 'Route element neu anlegen'
+ page_title: 'Routen-Element neu anlegen'
actions:
back_to_list: 'Zurück zur Übersicht'
edit:
- page_title: 'Route element bearbeiten'
+ page_title: 'Routen-Element bearbeiten'
actions:
back_to_list: 'Zurück zur Übersicht'
edit: 'Bearbeiten'
diff --git a/config/locales/views/sip_accounts/de.yml b/config/locales/views/sip_accounts/de.yml
index 2820336..8fe2300 100644
--- a/config/locales/views/sip_accounts/de.yml
+++ b/config/locales/views/sip_accounts/de.yml
@@ -11,11 +11,11 @@ de:
caller_name: 'Caller Name'
password: 'Passwort'
voicemail_pin: 'Anrufbeantworter PIN'
- phone_numbers: 'Telefonnummern'
+ phone_numbers: 'Tel.Nr.'
call_waiting: 'Anklopfen'
clir: 'Rufnummernunterdrückung (CLIR)'
clip: 'Rufnummernanzeige (CLIP)'
- hotdeskable: 'Hot-Desk fähig'
+ hotdeskable: 'Hot-Desk'
clip_no_screening: 'Spezifische Rufnummernanzeige (CLIP -no screening-)'
callforward_rules_act_per_sip_account: 'Rufweiterleitungen gelten für das gesamte SIP-Account'
online: 'Online'
diff --git a/config/locales/views/system_messages/de.yml b/config/locales/views/system_messages/de.yml
deleted file mode 100644
index d841d0b..0000000
--- a/config/locales/views/system_messages/de.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-de:
- system_messages:
- name: 'Systemnachricht'
- controller:
- successfuly_created: 'Eine Systemnachricht wurde erstellt.'
- successfuly_updated: 'Eine Systemnachricht wurde aktualisiert.'
- successfuly_destroyed: 'Eine Systemnachricht wurde gelöscht.'
- index:
- page_title: 'Systemnachrichten'
- user_id: 'Benutzer'
- content: 'Nachricht'
- actions:
- confirm_destroy: 'Sind Sie sicher, dass Sie diese Systemnachricht löschen möchten?'
- destroy: 'Löschen'
- edit: 'Bearbeiten'
- show: 'Anzeigen'
- create: 'Neu anlegen'
- show:
- page_title: 'Systemnachricht anzeigen'
- user_id: 'Benutzer'
- content: 'Nachricht'
- actions:
- confirm_destroy: 'Sind Sie sicher, dass Sie diese Systemnachricht löschen möchten?'
- destroy: 'Löschen'
- edit: 'Bearbeiten'
- view_all: 'Alle anzeigen'
- new:
- page_title: 'Neue Systemnachricht'
- edit:
- page_title: 'Systemnachricht bezüglich %{resource} bearbeiten'
- form:
- user_id:
- label: 'Benutzer'
- hint: ''
- content:
- label: 'Nachricht'
- hint: ''
- submit: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/system_messages/en.yml b/config/locales/views/system_messages/en.yml
deleted file mode 100644
index a039b10..0000000
--- a/config/locales/views/system_messages/en.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-en:
- system_messages:
- name: 'System message'
- controller:
- successfuly_created: 'Successfully created System message.'
- successfuly_updated: 'Successfully updated System message.'
- successfuly_destroyed: 'Successfully destroyed System message.'
- index:
- page_title: 'System messages'
- user_id: 'User'
- content: 'Content'
- actions:
- confirm_destroy: 'Are you sure you want to delete this element?'
- destroy: 'Delete'
- edit: 'Edit'
- show: 'View'
- create: 'New'
- show:
- page_title: 'Editing System message'
- user_id: 'User'
- content: 'Content'
- actions:
- confirm_destroy: 'Are you sure you want to delete this element?'
- destroy: 'Delete'
- edit: 'Edit'
- view_all: 'View All'
- new:
- page_title: 'New System message'
- edit:
- page_title: 'Editing System message %{resource}'
- form:
- user_id:
- label: 'User'
- hint: ''
- content:
- label: 'Content'
- hint: ''
- submit: 'Submit' \ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 9d47efc..6d7a2ad 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,20 +1,21 @@
Gemeinschaft42c::Application.routes.draw do
+ resources :intruders
+
+ resources :backup_jobs, :except => [:edit, :update]
+
scope :constraints => lambda{|req|%w(127.0.0.1).include? req.remote_addr} do
get "trigger/voicemail"
get "trigger/fax"
end
resources :call_routes do
+ collection {
+ post :sort
+ get :show_variables
+ }
resources :route_elements do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
- member do
- put 'move_higher'
- put 'move_lower'
+ collection { post :sort }
end
end
@@ -41,95 +42,54 @@ Gemeinschaft42c::Application.routes.draw do
resources :rows
end
+ resources :phone_numbers, :only => [:sort] do
+ collection { post :sort }
+ end
+
resources :acd_agents, :only => [] do
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
resources :automatic_call_distributors, :only => [] do
resources :acd_agents
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
resources :hunt_group_members, :only => [] do
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
resources :hunt_groups, :only => [] do
resources :hunt_group_members
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
resources :whitelists, :only => [] do
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
end
resources :access_authorizations, :only => [] do
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
resources :fax_documents
resources :fax_accounts, :only => [] do
resources :fax_documents
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
resources :gemeinschaft_setups, :only => [:new, :create]
-
+
resources :phone_number_ranges, :only => [] do
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
resources :conferences, :only => [] do
resources :conference_invitees
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
end
resources :phone_numbers, :only => [] do
@@ -228,9 +188,6 @@ Gemeinschaft42c::Application.routes.draw do
root :to => "page#index"
- get "wizards/new_initial_setup"
- post "wizards/create_initial_setup"
-
resources :users do
# Display all phone books that the current user owns:
resources :phone_books
@@ -271,31 +228,20 @@ Gemeinschaft42c::Application.routes.draw do
resources :callthroughs, :only => [] do
resources :access_authorizations
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
resources :whitelists
end
end
+ resources :softkeys, :only => [ :sort ] do
+ collection { post :sort }
+ end
+
resources :sip_accounts, :only => [] do
resources :phones_sip_accounts
- resources :phone_numbers do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
- resources :softkeys do
- member do
- put 'move_higher'
- put 'move_lower'
- end
- end
+ resources :phone_numbers
+ resources :softkeys
resources :call_histories do
collection do
delete 'destroy_multiple'
@@ -325,8 +271,6 @@ Gemeinschaft42c::Application.routes.draw do
resources :phone_book_entries, :only => [ :index, :show ] do
resources :phone_numbers do
member do
- put 'move_higher'
- put 'move_lower'
put 'call'
end
end
diff --git a/config/schedule.rb b/config/schedule.rb
new file mode 100644
index 0000000..0b5f0ca
--- /dev/null
+++ b/config/schedule.rb
@@ -0,0 +1,24 @@
+# Use this file to easily define all of your cron jobs.
+#
+# It's helpful, but not entirely necessary to understand cron before proceeding.
+# http://en.wikipedia.org/wiki/Cron
+
+# Example:
+#
+# set :output, "/path/to/my/cron_log.log"
+#
+# every 2.hours do
+# command "/usr/bin/some_great_command"
+# runner "MyModel.some_method"
+# rake "some:great:rake:task"
+# end
+#
+# every 4.days do
+# runner "AnotherModel.prune_old_records"
+# end
+
+every 1.day, :at => '4:00 am' do
+ rake "backup:daily_backup"
+end
+
+# Learn more: http://github.com/javan/whenever
diff --git a/db/migrate/20120127101726_create_system_messages.rb b/db/migrate/20120127101726_create_system_messages.rb
deleted file mode 100644
index 830f54a..0000000
--- a/db/migrate/20120127101726_create_system_messages.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class CreateSystemMessages < ActiveRecord::Migration
- def self.up
- create_table :system_messages do |t|
- t.integer :user_id
- t.string :content
- t.timestamps
- end
- end
-
- def self.down
- drop_table :system_messages
- end
-end
diff --git a/db/migrate/20130129154700_add_sso_key.rb b/db/migrate/20130129154700_add_sso_key.rb
new file mode 100644
index 0000000..2e47f39
--- /dev/null
+++ b/db/migrate/20130129154700_add_sso_key.rb
@@ -0,0 +1,9 @@
+class AddSsoKey < ActiveRecord::Migration
+ def up
+ GsParameter.create(:name => 'SingleSignOnEnvUserNameKey', :section => 'Generic', :value => '', :class_type => 'Nil', :description => 'When set to a string this env variable will be used to authenticate the user. e.g. REMOTE_USER')
+ end
+
+ def down
+ GsParameter.create(:name => 'SingleSignOnEnvUserNameKey').destroy_all
+ end
+end
diff --git a/db/migrate/20130130185300_add_no_copy_headers.rb b/db/migrate/20130130185300_add_no_copy_headers.rb
new file mode 100644
index 0000000..aa96653
--- /dev/null
+++ b/db/migrate/20130130185300_add_no_copy_headers.rb
@@ -0,0 +1,9 @@
+class AddNoCopyHeaders < ActiveRecord::Migration
+ def up
+ GsParameter.create(:entity => 'dialplan', :section => 'variables', :name => 'sip_copy_custom_headers', :value => 'false', :class_type => 'Boolean', :description => 'Controls passing SIP headers from one call leg to another.')
+ end
+
+ def down
+ GsParameter.where(:entity => 'dialplan', :section => 'variables', :name => 'sip_copy_custom_headers').destroy_all
+ end
+end
diff --git a/db/migrate/20130202140927_add_trunk_access_code_to_gemeinschaft_setup.rb b/db/migrate/20130202140927_add_trunk_access_code_to_gemeinschaft_setup.rb
new file mode 100644
index 0000000..82fa3ad
--- /dev/null
+++ b/db/migrate/20130202140927_add_trunk_access_code_to_gemeinschaft_setup.rb
@@ -0,0 +1,5 @@
+class AddTrunkAccessCodeToGemeinschaftSetup < ActiveRecord::Migration
+ def change
+ add_column :gemeinschaft_setups, :trunk_access_code, :string
+ end
+end
diff --git a/db/migrate/20130203164500_remove_perimeter_parameters.rb b/db/migrate/20130203164500_remove_perimeter_parameters.rb
new file mode 100644
index 0000000..8c37174
--- /dev/null
+++ b/db/migrate/20130203164500_remove_perimeter_parameters.rb
@@ -0,0 +1,16 @@
+class RemovePerimeterParameters < ActiveRecord::Migration
+ def up
+ GsParameter.where(:entity => 'perimeter', :section => 'general', :name => 'malicious_contact_count').destroy_all
+ GsParameter.where(:entity => 'perimeter', :section => 'general', :name => 'malicious_contact_time_span').destroy_all
+ GsParameter.where(:entity => 'perimeter', :section => 'general', :name => 'ban_futile').destroy_all
+ GsParameter.where(:entity => 'perimeter', :section => 'general', :name => 'execute').destroy_all
+
+ end
+
+ def down
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'malicious_contact_count', :value => 20, :class_type => 'Integer')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'malicious_contact_time_span', :value => 2, :class_type => 'Integer')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'ban_futile', :value => 5, :class_type => 'Integer')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'execute', :value => 'sudo /usr/local/bin/ban_ip.sh {ip_address}', :class_type => 'String')
+ end
+end
diff --git a/db/migrate/20130203165800_add_perimeter_parameters.rb b/db/migrate/20130203165800_add_perimeter_parameters.rb
new file mode 100644
index 0000000..23e0157
--- /dev/null
+++ b/db/migrate/20130203165800_add_perimeter_parameters.rb
@@ -0,0 +1,23 @@
+class AddPerimeterParameters < ActiveRecord::Migration
+ def up
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'contact_count_threshold', :value => '10', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'contact_span_threshold', :value => '2', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'name_changes_threshold', :value => '5', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'ban_threshold', :value => '20', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'ban_tries', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'blacklist_file', :value => '/var/opt/gemeinschaft/firewall/blacklist', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'blacklist_file_comment', :value => '# PERIMETER_BAN - points: {points}, generated: {date}', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'blacklist_file_entry', :value => '{received_ip} udp 5060', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'ban_command', :value => 'sudo /sbin/service shorewall refresh', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks', :name => 'check_frequency', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks', :name => 'check_username_scan', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks', :name => 'check_bad_headers', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers', :name => 'user_agent', :value => '^friendly.scanner$', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers', :name => 'to_user', :value => '^%d+', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers', :name => 'auth_result', :value => '^FORBIDDEN$', :class_type => 'String', :description => '')
+ end
+
+ def down
+ GsParameter.where(:entity => 'perimeter').destroy_all
+ end
+end
diff --git a/db/migrate/20130203174300_start_perimeter_defense.rb b/db/migrate/20130203174300_start_perimeter_defense.rb
new file mode 100644
index 0000000..15838bb
--- /dev/null
+++ b/db/migrate/20130203174300_start_perimeter_defense.rb
@@ -0,0 +1,10 @@
+class StartPerimeterDefense < ActiveRecord::Migration
+ def up
+ module_index = GsParameter.where(:entity => 'events', :section => 'modules').all.count + 1;
+ GsParameter.create(:entity => 'events', :section => 'modules', :name => 'perimeter_defense', :value => module_index, :class_type => 'Integer')
+ end
+
+ def down
+ GsParameter.where(:entity => 'events', :section => 'modules', :name => 'perimeter_defense').destroy_all
+ end
+end
diff --git a/db/migrate/20130204065900_split_perimeter_parameters.rb b/db/migrate/20130204065900_split_perimeter_parameters.rb
new file mode 100644
index 0000000..b29bb29
--- /dev/null
+++ b/db/migrate/20130204065900_split_perimeter_parameters.rb
@@ -0,0 +1,30 @@
+class SplitPerimeterParameters < ActiveRecord::Migration
+ def up
+ GsParameter.where(:entity => 'perimeter', :section => 'checks').destroy_all
+ GsParameter.where(:entity => 'perimeter', :section => 'bad_headers').destroy_all
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'ban_command', :value => 'sudo /sbin/service shorewall refresh', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks_register', :name => 'check_frequency', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks_register', :name => 'check_username_scan', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks_register', :name => 'check_bad_headers', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks_call', :name => 'check_frequency', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks_call', :name => 'check_bad_headers', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers_register', :name => 'user_agent', :value => '^friendly.scanner$', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers_register', :name => 'to_user', :value => '^%d+', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers_register', :name => 'auth_result', :value => '^FORBIDDEN$', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers_call', :name => 'user_agent', :value => '^friendly.scanner$', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers_call', :name => 'hangup_cause', :value => '^MANDATORY_IE_MISSING', :class_type => 'String', :description => '')
+ end
+
+ def down
+ GsParameter.where(:entity => 'perimeter', :section => 'checks_register').destroy_all
+ GsParameter.where(:entity => 'perimeter', :section => 'checks_call').destroy_all
+ GsParameter.where(:entity => 'perimeter', :section => 'bad_headers_register').destroy_all
+ GsParameter.where(:entity => 'perimeter', :section => 'bad_headers_call').destroy_all
+ GsParameter.create(:entity => 'perimeter', :section => 'checks', :name => 'check_frequency', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks', :name => 'check_username_scan', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'checks', :name => 'check_bad_headers', :value => '1', :class_type => 'Integer', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers', :name => 'user_agent', :value => '^friendly.scanner$', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers', :name => 'to_user', :value => '^%d+', :class_type => 'String', :description => '')
+ GsParameter.create(:entity => 'perimeter', :section => 'bad_headers', :name => 'auth_result', :value => '^FORBIDDEN$', :class_type => 'String', :description => '')
+ end
+end
diff --git a/db/migrate/20130205102838_create_backup_jobs.rb b/db/migrate/20130205102838_create_backup_jobs.rb
new file mode 100644
index 0000000..0994939
--- /dev/null
+++ b/db/migrate/20130205102838_create_backup_jobs.rb
@@ -0,0 +1,16 @@
+class CreateBackupJobs < ActiveRecord::Migration
+ def self.up
+ create_table :backup_jobs do |t|
+ t.datetime :started_at
+ t.datetime :finished_at
+ t.string :state
+ t.string :directory
+ t.integer :size_of_the_backup
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :backup_jobs
+ end
+end
diff --git a/db/migrate/20130205151844_add_queue_to_delayed_jobs.rb b/db/migrate/20130205151844_add_queue_to_delayed_jobs.rb
new file mode 100644
index 0000000..072c8d4
--- /dev/null
+++ b/db/migrate/20130205151844_add_queue_to_delayed_jobs.rb
@@ -0,0 +1,9 @@
+class AddQueueToDelayedJobs < ActiveRecord::Migration
+ def self.up
+ add_column :delayed_jobs, :queue, :string
+ end
+
+ def self.down
+ remove_column :delayed_jobs, :queue
+ end
+end
diff --git a/db/migrate/20130206144829_add_backup_file_to_backup_job.rb b/db/migrate/20130206144829_add_backup_file_to_backup_job.rb
new file mode 100644
index 0000000..e02f2b3
--- /dev/null
+++ b/db/migrate/20130206144829_add_backup_file_to_backup_job.rb
@@ -0,0 +1,5 @@
+class AddBackupFileToBackupJob < ActiveRecord::Migration
+ def change
+ add_column :backup_jobs, :backup_file, :string
+ end
+end
diff --git a/db/migrate/20130207082728_remove_size_of_the_backup_from_backup_job.rb b/db/migrate/20130207082728_remove_size_of_the_backup_from_backup_job.rb
new file mode 100644
index 0000000..a902fd2
--- /dev/null
+++ b/db/migrate/20130207082728_remove_size_of_the_backup_from_backup_job.rb
@@ -0,0 +1,9 @@
+class RemoveSizeOfTheBackupFromBackupJob < ActiveRecord::Migration
+ def up
+ remove_column :backup_jobs, :size_of_the_backup
+ end
+
+ def down
+ add_column :backup_jobs, :size_of_the_backup, :string
+ end
+end
diff --git a/db/migrate/20130208065700_add_softkeyable_to_softkey.rb b/db/migrate/20130208065700_add_softkeyable_to_softkey.rb
new file mode 100644
index 0000000..deae9a0
--- /dev/null
+++ b/db/migrate/20130208065700_add_softkeyable_to_softkey.rb
@@ -0,0 +1,16 @@
+class AddSoftkeyableToSoftkey < ActiveRecord::Migration
+ def up
+ add_column :softkeys, :softkeyable_type, :string
+ add_column :softkeys, :softkeyable_id, :integer
+ Softkey.where('call_forward_id > 0').each do |softkey|
+ softkey.update_attributes( :softkeyable_type => 'CallForward', :softkeyable_id => softkey.call_forward_id )
+ end
+ remove_column :softkeys, :call_forward_id
+ end
+
+ def down
+ remove_column :softkeys, :softkeyable_type
+ remove_column :softkeys, :softkeyable_id
+ add_column :softkeys, :call_forward_id, :integer
+ end
+end
diff --git a/db/migrate/20130210075617_create_intruders.rb b/db/migrate/20130210075617_create_intruders.rb
new file mode 100644
index 0000000..fc944cc
--- /dev/null
+++ b/db/migrate/20130210075617_create_intruders.rb
@@ -0,0 +1,28 @@
+class CreateIntruders < ActiveRecord::Migration
+ def self.up
+ create_table :intruders do |t|
+ t.string :list_type
+ t.string :key
+ t.integer :points
+ t.integer :bans
+ t.datetime :ban_last
+ t.datetime :ban_end
+ t.string :contact_ip
+ t.integer :contact_port
+ t.integer :contact_count
+ t.datetime :contact_last
+ t.float :contacts_per_second
+ t.float :contacts_per_second_max
+ t.string :user_agent
+ t.string :to_user
+ t.string :comment
+ t.timestamps
+ end
+
+ add_index :intruders, :key, :unique => true
+ end
+
+ def self.down
+ drop_table :intruders
+ end
+end
diff --git a/db/migrate/20130212071000_default_profile_to_template.rb b/db/migrate/20130212071000_default_profile_to_template.rb
new file mode 100644
index 0000000..d3fd89c
--- /dev/null
+++ b/db/migrate/20130212071000_default_profile_to_template.rb
@@ -0,0 +1,13 @@
+class DefaultProfileToTemplate < ActiveRecord::Migration
+ def up
+ GsParameter.where(:entity => 'sofia', :section => 'profile:gemeinschaft').each do |profile|
+ profile.update_attributes(:section => 'profile')
+ end
+ end
+
+ def down
+ GsParameter.where(:entity => 'sofia', :section => 'profile').each do |profile|
+ profile.update_attributes(:section => 'profile:gemeinschaft')
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 7bae5fd..fc2b635 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20130128121800) do
+ActiveRecord::Schema.define(:version => 20130212071000) do
create_table "access_authorizations", :force => true do |t|
t.string "access_authorizationable_type"
@@ -124,6 +124,16 @@ ActiveRecord::Schema.define(:version => 20130128121800) do
t.string "music"
end
+ create_table "backup_jobs", :force => true do |t|
+ t.datetime "started_at"
+ t.datetime "finished_at"
+ t.string "state"
+ t.string "directory"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.string "backup_file"
+ end
+
create_table "call_forward_cases", :force => true do |t|
t.string "value"
t.datetime "created_at", :null => false
@@ -358,6 +368,7 @@ ActiveRecord::Schema.define(:version => 20130128121800) do
t.string "locked_by"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
+ t.string "queue"
end
add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority"
@@ -540,6 +551,7 @@ ActiveRecord::Schema.define(:version => 20130128121800) do
t.string "default_area_code"
t.string "default_company_name"
t.string "default_system_email"
+ t.string "trunk_access_code"
end
create_table "gs_cluster_sync_log_entries", :force => true do |t|
@@ -634,6 +646,28 @@ ActiveRecord::Schema.define(:version => 20130128121800) do
t.string "hostname", :limit => 256
end
+ create_table "intruders", :force => true do |t|
+ t.string "list_type"
+ t.string "key"
+ t.integer "points"
+ t.integer "bans"
+ t.datetime "ban_last"
+ t.datetime "ban_end"
+ t.string "contact_ip"
+ t.integer "contact_port"
+ t.integer "contact_count"
+ t.datetime "contact_last"
+ t.float "contacts_per_second"
+ t.float "contacts_per_second_max"
+ t.string "user_agent"
+ t.string "to_user"
+ t.string "comment"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+ add_index "intruders", ["key"], :name => "index_intruders_on_key", :unique => true
+
create_table "languages", :force => true do |t|
t.string "name"
t.string "code"
@@ -939,15 +973,9 @@ ActiveRecord::Schema.define(:version => 20130128121800) do
t.datetime "updated_at", :null => false
t.integer "sip_account_id"
t.integer "softkey_function_id"
- t.integer "call_forward_id"
t.string "uuid"
- end
-
- create_table "system_messages", :force => true do |t|
- t.integer "user_id"
- t.string "content"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.string "softkeyable_type"
+ t.integer "softkeyable_id"
end
create_table "tasks", :id => false, :force => true do |t|
diff --git a/lib/freeswitch_event.rb b/lib/freeswitch_event.rb
index b6e5cbc..68d9df2 100644
--- a/lib/freeswitch_event.rb
+++ b/lib/freeswitch_event.rb
@@ -44,8 +44,8 @@ class FreeswitchEventSocket
@socket.close
end
- def read()
- return @socket.recv(1024)
+ def read(read_bytes=1024)
+ return @socket.recv(read_bytes)
end
def result()
@@ -130,4 +130,20 @@ class FreeswitchAPI
return false
end
+
+ def self.channel_variable_get(channel_uuid, variable_name)
+ result = nil
+ event = FreeswitchEventSocket.new()
+ if event && event.connect()
+ event.command( "api uuid_getvar #{channel_uuid} #{variable_name}")
+ event_result = event.result()
+ if event_result && event_result["Content-Type"] == 'api/response' && event_result["Content-Length"].to_i > 0
+ result = event.read(event_result["Content-Length"].to_i)
+ end
+ event.close()
+ end
+
+ return result
+ end
+
end
diff --git a/lib/tasks/backup.rake b/lib/tasks/backup.rake
new file mode 100644
index 0000000..c285e1f
--- /dev/null
+++ b/lib/tasks/backup.rake
@@ -0,0 +1,6 @@
+namespace :backup do
+ desc "Backup the system"
+ task :daily_backup => :environment do
+ # This would be the daily backup.
+ end
+end \ No newline at end of file
diff --git a/lib/tasks/cvs_user_import.rake b/lib/tasks/csv_user_import.rake
index 81959d5..81959d5 100644
--- a/lib/tasks/cvs_user_import.rake
+++ b/lib/tasks/csv_user_import.rake
diff --git a/lib/tasks/gs_cluster.rake b/lib/tasks/gs_cluster.rake
index 7b49ebb..c248c32 100644
--- a/lib/tasks/gs_cluster.rake
+++ b/lib/tasks/gs_cluster.rake
@@ -201,10 +201,14 @@ namespace :gs_cluster do
remote_objects(remote_site, local_node_id, last_sync, Softkey).each do |remote_object|
attributes = make_hash(remote_object.attributes)
attributes[:sip_account_id] = SipAccount.where(:uuid => attributes[:sip_account_uuid]).first.try(:id)
- attributes[:call_forward_id] = CallForward.where(:uuid => attributes[:call_forward_uuid]).first.try(:id)
+
+ if ! attributes[:softkeyable_uuid].blank?
+ attributes[:softkeyable_id] = attributes[:softkeyable_type].constantize.where(:uuid => attributes[:softkeyable_uuid]).first.try(:id)
+ end
+
attributes[:softkey_function_id] = SoftkeyFunction.where(:name => attributes[:function]).first.try(:id)
attributes.delete(:sip_account_uuid)
- attributes.delete(:call_forward_uuid)
+ attributes.delete(:softkeyable_uuid)
attributes.delete(:softkey_function)
process_object(Softkey, Softkey, Softkey.where(:uuid => attributes[:uuid]).first, attributes)
end
diff --git a/misc/freeswitch/conf/freeswitch.xml b/misc/freeswitch/conf/freeswitch.xml
index fd6ab67..a5fe873 100644
--- a/misc/freeswitch/conf/freeswitch.xml
+++ b/misc/freeswitch/conf/freeswitch.xml
@@ -466,6 +466,470 @@
</macros>
</phrases>
</language>
+ <language name="de" say-module="de" sound-prefix="/opt/freeswitch/sounds/de/de/callie">
+ <phrases>
+ <macros>
+ <macro name="voicemail_hello">
+ <input pattern="(.*)">
+ <match>
+ <action function="play-file" data="voicemail/vm-hello.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_enter_id">
+ <input pattern="(.*)">
+ <match>
+ <action function="play-file" data="voicemail/vm-enter_id.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_enter_pass">
+ <input pattern="(.*)">
+ <match>
+ <action function="play-file" data="voicemail/vm-enter_pass.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_fail_auth">
+ <input pattern="(.*)">
+ <match>
+ <action function="play-file" data="voicemail/vm-fail_auth.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_goodbye">
+ <input pattern="(.*)">
+ <match>
+ <action function="play-file" data="voicemail/vm-goodbye.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_abort">
+ <input pattern="(.*)">
+ <match>
+ <action function="play-file" data="voicemail/vm-abort.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_message_count">
+ <input pattern="^(1):(.*)$" break_on_match="true">
+ <match>
+ <action function="play-file" data="voicemail/vm-you_have.wav"/>
+ <action function="say" data="$1" method="pronounced" type="items"/>
+ <action function="play-file" data="voicemail/vm-$2.wav"/>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ </match>
+ </input>
+ <input pattern="^(\d+):(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-you_have.wav"/>
+ <action function="say" data="$1" method="pronounced" type="items"/>
+ <action function="play-file" data="voicemail/vm-$2.wav"/>
+ <action function="play-file" data="voicemail/vm-messages.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_menu">
+ <input pattern="^([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*])$">
+ <match>
+ <action function="play-file" data="voicemail/vm-listen_new.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="execute" data="sleep(100)"/>
+ <action function="play-file" data="voicemail/vm-listen_saved.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$2" method="pronounced" type="name_spelled"/>
+ <action function="execute" data="sleep(100)"/>
+ <action function="play-file" data="voicemail/vm-advanced.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$3" method="pronounced" type="name_spelled"/>
+ <action function="execute" data="sleep(100)"/>
+ <action function="play-file" data="voicemail/vm-to_exit.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$4" method="pronounced" type="name_phonetic"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_config_menu">
+ <input pattern="^([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*])$">
+ <match>
+ <action function="play-file" data="voicemail/vm-to_record_greeting.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="execute" data="sleep(100)"/>
+ <action function="play-file" data="voicemail/vm-choose_greeting.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$2" method="pronounced" type="name_spelled"/>
+ <action function="execute" data="sleep(100)"/>
+ <action function="play-file" data="voicemail/vm-record_name2.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$3" method="pronounced" type="name_spelled"/>
+ <action function="execute" data="sleep(100)"/>
+ <action function="play-file" data="voicemail/vm-change_password.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$4" method="pronounced" type="name_spelled"/>
+ <action function="execute" data="sleep(100)"/>
+ <action function="play-file" data="voicemail/vm-main_menu.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$5" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_record_name">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-record_name1.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_record_file_check">
+ <input pattern="^([0-9#*]):([0-9#*]):([0-9#*])$">
+ <match>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-listen_to_recording.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$2" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-save_recording.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$3" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-rerecord.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_record_urgent_check">
+ <input pattern="^([0-9#*]):([0-9#*])$">
+ <match>
+ <action function="play-file" data="voicemail/vm-mark-urgent.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-continue.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$2" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_forward_prepend">
+ <input pattern="^([0-9#*]):([0-9#*])$">
+ <match>
+ <action function="play-file" data="voicemail/vm-forward_add_intro.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-send_message_now.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$2" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_forward_message_enter_extension">
+ <input pattern="^([0-9#*])$">
+ <match>
+ <action function="play-file" data="voicemail/vm-forward_enter_ext.wav"/>
+ <action function="play-file" data="voicemail/vm-followed_by.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_invalid_extension">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-that_was_an_invalid_ext.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_listen_file_check">
+ <input pattern="^([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-listen_to_recording.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-save_recording.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$2" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-delete_recording.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$3" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-forward_to_email.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$4" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-return_call.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$5" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-to_forward.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$6" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ <input pattern="^([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*])$">
+ <match>
+ <action function="play-file" data="voicemail/vm-listen_to_recording.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-save_recording.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$2" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-delete_recording.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$3" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-return_call.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$5" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-to_forward.wav"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$6" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_choose_greeting">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-choose_greeting_choose.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_choose_greeting_fail">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-choose_greeting_fail.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_record_greeting">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-record_greeting.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_record_message">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-record_message.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_greeting_selected">
+ <input pattern="^(\d+)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-greeting.wav"/>
+ <action function="say" data="$1" method="pronounced" type="items"/>
+ <action function="play-file" data="voicemail/vm-selected.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_play_greeting">
+ <input pattern="^(\d+)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-person.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-not_available.wav"/>
+ </match>
+ </input>
+ <input pattern="^name:(.+)$">
+ <match>
+ <action function="play-file" data="$1"/>
+ <action function="play-file" data="voicemail/vm-not_available.wav"/>
+ </match>
+ </input>
+ <input pattern="^greeting:(.+)$">
+ <match>
+ <action function="play-file" data="$1"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_say_number">
+ <input pattern="^(\d+)$">
+ <match>
+ <action function="say" data="$1" method="pronounced" type="items"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_say_message_number">
+ <input pattern="^([a-z]+):(\d+)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ <action function="play-file" data="voicemail/vm-message_number.wav"/>
+ <action function="say" data="$2" method="pronounced" type="items"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_say_phone_number">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_say_name">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_ack">
+ <input pattern="^(too-small)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-too-small.wav"/>
+ </match>
+ </input>
+ <input pattern="^(deleted)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ </match>
+ </input>
+ <input pattern="^(saved)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-saved2.wav"/>
+ </match>
+ </input>
+ <input pattern="^(emailed)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ </match>
+ </input>
+ <input pattern="^(marked-urgent)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_say_date">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="say" data="$1" method="pronounced" type="current_date_time"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="voicemail_disk_quota_exceeded">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-mailbox_full.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="valet_announce_ext">
+ <input pattern="^([^\:]+):(.*)$">
+ <match>
+ <action function="say" data="$2" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="valet_lot_full">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="tone_stream://%(275,10,600);%(275,100,300)"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="valet_lot_empty">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="tone_stream://%(275,10,600);%(275,100,300)"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="logged_in">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="ivr/ivr-you_are_now_logged_in.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="logged_out">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="ivr/ivr-you_are_now_logged_out.wav"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="acd_announce_position_enter">
+ <input pattern="^([0-9]+)$">
+ <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>
+ <macro name="acd_announce_position_change">
+ <input pattern="^1$">
+ <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>
+ <input pattern="^([0-9]+)$">
+ <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>
+ </macro>
+ <macro name="acd_announce_position_periodic">
+ <input pattern="^1$">
+ <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>
+ <input pattern="^([0-9]+)$">
+ <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>
+ </macro>
+ <macro name="acd_announce_call_agents">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="$1"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="acd_greeting">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="$1"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="acd_goodbye">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="$1"/>
+ </match>
+ </input>
+ </macro>
+ <macro name="acd_agent_status">
+ <input pattern="^active$">
+ <match>
+ <action function="play-file" data="ivr/ivr-you_are_now_logged_in.wav"/>
+ </match>
+ </input>
+ <input pattern="^inactive$">
+ <match>
+ <action function="play-file" data="ivr/ivr-you_are_now_logged_out.wav"/>
+ </match>
+ </input>
+ </macro>
+ </macros>
+ </phrases>
+ </language>
</section>
<section name="configuration" description="Gemeinschaft5 FreeSwitch configuration">
<configuration name="acl.conf" description="Network Lists">
@@ -632,6 +1096,7 @@
<load module="mod_local_stream"/>
<load module="mod_tone_stream"/>
<load module="mod_say_en"/>
+ <load module="mod_say_de"/>
<load module="mod_spandsp"/>
<load module="mod_snmp"/>
<load module="mod_dingaling"/>
@@ -639,6 +1104,7 @@
</configuration>
<configuration name="lua.conf" description="LUA Configuration">
<settings>
+ <param name="module-directory" value="/usr/lib/i386-linux-gnu/lua/5.1/?.so;"/>
<param name="script-directory" value="/usr/share/freeswitch/scripts/?.lua;/usr/share/lua/5.1/?.lua;"/>
<param name="xml-handler-script" value="configuration.lua"/>
<param name="xml-handler-bindings" value="directory|configuration"/>
diff --git a/misc/freeswitch/scripts/common/database.lua b/misc/freeswitch/scripts/common/database.lua
index 1f39135..345f69d 100644
--- a/misc/freeswitch/scripts/common/database.lua
+++ b/misc/freeswitch/scripts/common/database.lua
@@ -16,6 +16,7 @@ function Database.new(self, arg)
self.class = 'database';
self.log = arg.log;
self.conn = nil;
+ self.ignore_on_update = arg.ignore_on_update or {};
return object;
end
@@ -71,6 +72,45 @@ function Database.last_insert_id(self)
end
+function Database.insert_or_update(self, db_table, record, use_on_update)
+ ignore_on_update = ignore_on_update or self.ignore_on_update;
+ local record_sql_create = {};
+ local record_sql_update = {};
+
+ for key, value in pairs(record) do
+ if ignore_on_update[key] ~= false then
+ table.insert(record_sql_update, self:key_value(key, value));
+ end
+ table.insert(record_sql_create, self:key_value(key, value));
+ end
+
+ local sql_query = 'INSERT INTO `' .. db_table .. '` SET ' .. table.concat(record_sql_create, ', ') .. ' ON DUPLICATE KEY UPDATE ' .. table.concat(record_sql_update, ', ');
+
+ return self:query(sql_query);
+end
+
+
+function Database.key_value(self, key, value)
+ return self:escape(key, '`') .. ' = ' .. self:escape(value, '"');
+end
+
+
+function Database.escape(self, value, str_quotes)
+ str_quotes = str_quotes or '';
+ if type(value) == 'boolean' then
+ return tostring(value):upper();
+ elseif type(value) == 'number' then
+ return tostring(value);
+ elseif type(value) == 'string' then
+ return str_quotes .. value:gsub('"', '\\"'):gsub("'", "\\'") .. str_quotes;
+ elseif type(value) == 'table' and value.raw then
+ return tostring(value[1]);
+ else
+ return 'NULL';
+ end
+end
+
+
function Database.release(self)
if self.conn then
self.conn:release();
diff --git a/misc/freeswitch/scripts/common/fapi.lua b/misc/freeswitch/scripts/common/fapi.lua
index 5b96633..b749a69 100644
--- a/misc/freeswitch/scripts/common/fapi.lua
+++ b/misc/freeswitch/scripts/common/fapi.lua
@@ -32,8 +32,10 @@ function FApi.return_result(self, result, positive, negative, unspecified)
return negative;
elseif result:match('^+OK') then
return positive;
- else
+ elseif type(unspecified) ~= 'nil' then
return unspecified;
+ else
+ return result;
end
end
@@ -75,6 +77,7 @@ function FApi.create_uuid(self, uuid)
end
function FApi.execute(self, function_name, function_parameters)
+ function_parameters = function_parameters or '';
local result = self.fs_api:execute(function_name, function_parameters);
return self:return_result(result, true);
end
diff --git a/misc/freeswitch/scripts/common/intruder.lua b/misc/freeswitch/scripts/common/intruder.lua
new file mode 100644
index 0000000..083ec37
--- /dev/null
+++ b/misc/freeswitch/scripts/common/intruder.lua
@@ -0,0 +1,51 @@
+-- Gemeinschaft 5 module: intruder class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+
+Intruder = {}
+
+
+function Intruder.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.log = arg.log;
+ self.class = 'intruder'
+ self.database = arg.database;
+
+ return object;
+end
+
+
+function Intruder.update_blacklist(self, event)
+ local intruder_record = {
+ list_type = 'blacklist',
+ key = event.key,
+ points = event.points,
+ bans = event.record.banned,
+ contact_ip = event.received_ip,
+ contact_port = event.received_port,
+ contact_count = event.record.contact_count + 1,
+ contact_last = { 'FROM_UNIXTIME(' .. tostring(math.floor(event.timestamp/1000000)) .. ')', raw = true },
+ contacts_per_second = event.contacts_per_second,
+ contacts_per_second_max = event.contacts_per_second_max,
+ user_agent = event.user_agent,
+ to_user = event.to_user,
+ comment = 'Permimeter',
+ created_at = {'NOW()', raw = true },
+ updated_at = {'NOW()', raw = true },
+ };
+
+ if tonumber(event.ban_time) then
+ intruder_record.ban_last = { 'FROM_UNIXTIME(' .. event.ban_time .. ')', raw = true };
+ end
+ if tonumber(event.ban_end) then
+ intruder_record.ban_end = { 'FROM_UNIXTIME(' .. event.ban_end .. ')', raw = true };
+ end
+
+ self.database:insert_or_update('intruders', intruder_record, { created_at = false, comment = false });
+end
diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua
new file mode 100644
index 0000000..0815d33
--- /dev/null
+++ b/misc/freeswitch/scripts/common/perimeter.lua
@@ -0,0 +1,241 @@
+-- Gemeinschaft 5 module: perimeter class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+
+Perimeter = {}
+
+
+function Perimeter.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.log = arg.log;
+ self.class = 'perimeter'
+ self.database = arg.database;
+ self.domain = arg.domain;
+ self.sources = {};
+
+ self.checks_available = {
+ check_frequency = self.check_frequency,
+ check_username_scan = self.check_username_scan,
+ check_bad_headers = self.check_bad_headers,
+ };
+
+ return object;
+end
+
+
+function Perimeter.setup(self, event)
+ require 'common.configuration_table';
+ local config = common.configuration_table.get(self.database, 'perimeter');
+
+ self.contact_count_threshold = 10;
+ self.contact_span_threshold = 2;
+ self.name_changes_threshold = 2;
+ self.blacklist_file = '/var/opt/gemeinschaft/firewall/blacklist';
+ self.blacklist_file_comment = '# PERIMETER_BAN - points: {points}, generated: {date}';
+ self.blacklist_file_entry = '{received_ip} udp 5060';
+ self.ban_command = 'sudo /sbin/service shorewall refresh';
+ self.ban_threshold = 20;
+ self.ban_tries = 1;
+ self.checks = { register = {}, call = {} };
+ self.bad_headers = { register = {}, call = {} };
+
+ if config and config.general then
+ for key, value in pairs(config.general) do
+ self[key] = value;
+ end
+ end
+
+ self.checks.register = config.checks_register or {};
+ self.checks.call = config.checks_call or {};
+ self.bad_headers.register = config.bad_headers_register;
+ self.bad_headers.call = config.bad_headers_call;
+
+ self.log:info('[perimeter] PERIMETER - setup perimeter defense');
+end
+
+
+function Perimeter.record_load(self, event)
+ if not self.sources[event.key] then
+ self.sources[event.key] = {
+ contact_first = event.timestamp,
+ contact_last = event.timestamp,
+ contact_count = 0,
+ span_contact_count = 0,
+ span_start = event.timestamp,
+ points = 0,
+ banned = 0,
+ };
+ end
+
+ return self.sources[event.key];
+end
+
+
+function Perimeter.format_date(self, value)
+ local epoch = tonumber(tostring(value/1000000):match('^(%d-)%.'));
+ return os.date('%Y-%m-%d %X', tonumber(epoch)) .. '.' .. (value-(epoch*1000000));
+end
+
+
+function Perimeter.record_update(self, event)
+ event.record.contact_last = event.timestamp;
+ event.record.contact_count = event.record.contact_count + 1;
+ event.record.points = event.points or event.record.points;
+ event.record.span_start = event.span_start or event.record.span_start;
+ event.record.span_contact_count = (event.span_contact_count or event.record.span_contact_count) + 1;
+ event.record.users = event.users or event.record.users;
+end
+
+
+function Perimeter.check(self, event)
+ if not event or not event.key then
+ self.log:warning('[perimeter] PERIMETER_CHECK - no event/key');
+ return;
+ end
+
+ event.record = self:record_load(event);
+ 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
+ local result = self.checks_available[check_name](self, event);
+ if tonumber(result) then
+ event.points = (event.points or event.record.points) + result * check_points;
+ end
+ end
+ end
+ end
+
+ if tonumber(event.points) and event.points < 0 then
+ event.points = 0;
+ end
+
+ if event.points then
+ self.log:info('[', event.key, '/', event.sequence, '] PERIMETER suspicion rising - points: ', event.points,', ', event.action, '=', event.class, ', from: ', event.from_user, '@', event.from_host, ', to: ', event.to_user, '@', event.to_host, ', user_agent: ', event.user_agent);
+ end
+
+ if (event.points or event.record.points) > self.ban_threshold and event.record.banned <= self.ban_tries then
+ if event.record.banned > 0 and event.record.banned == self.ban_tries then
+ self.log:warning('[', event.key, '/', event.sequence, '] PERIMETER_BAN_FUTILE - points: ', event.points,', event: ', event.class, ', from: ', event.from_user, '@', event.from_host, ', to: ', event.to_user, '@', event.to_host);
+ else
+ self.log:notice('[', event.key, '/', event.sequence, '] PERIMETER_BAN - threshold reached: ', event.points,', event: ', event.class, ', from: ', event.from_user, '@', event.from_host, ', to: ', event.to_user, '@', event.to_host);
+ if event.record.banned == 0 then
+ self:append_blacklist_file(event);
+ end
+ self:execute_ban(event);
+ event.ban_time = os.time();
+ end
+
+ event.record.banned = event.record.banned + 1;
+ event.span_start = event.timestamp;
+ event.span_contact_count = 0;
+ event.points = 0;
+ end
+
+ if event.points then
+ self:update_intruder(event);
+ end
+
+ self:record_update(event);
+end
+
+
+function Perimeter.check_frequency(self, event)
+ if event.record.span_contact_count >= self.contact_count_threshold then
+ self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_FREQUENCY_CHECK - contacts: ', event.record.span_contact_count, ' in < ', (event.timestamp - event.record.span_start)/1000000, ' sec, threshold: ', self.contact_count_threshold, ' in ', self.contact_span_threshold, ' sec');
+ event.span_contact_count = 0;
+ event.span_start = event.timestamp;
+ event.contacts_per_second = event.record.span_contact_count / ((event.timestamp - event.record.span_start)/1000000)
+ return 1;
+ elseif (event.timestamp - event.record.span_start) > (self.contact_span_threshold * 1000000) then
+ event.span_contact_count = 0;
+ event.span_start = event.timestamp;
+ end
+end
+
+
+function Perimeter.check_username_scan(self, event)
+ if not event.to_user then
+ return;
+ end
+
+ if not event.record.users or tostring(event.auth_result) == 'SUCCESS' or tostring(event.auth_result) == 'RENEWED' then
+ event.users = { event.to_user };
+ return;
+ end
+
+ if #event.record.users >= self.name_changes_threshold then
+ self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_USER_SCAN - user names: ', #event.record.users, ', threshold: ', self.name_changes_threshold);
+ event.users = {};
+ return 1;
+ else
+ for index=1, #event.record.users do
+ if event.record.users[index] == tostring(event.to_user) then
+ return
+ end
+ end
+
+ if not event.users then
+ event.users = event.record.users or {};
+ end
+ table.insert(event.users, tostring(event.to_user));
+ end
+end
+
+
+function Perimeter.check_bad_headers(self, event)
+ local points = nil;
+ for name, pattern in pairs(self.bad_headers[event.action]) do
+ pattern = self:expand_variables(pattern, event);
+ local success, result = pcall(string.find, event[name], pattern);
+ if success and result then
+ self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern);
+ points = (points or 0) + 1;
+ end
+ end
+
+ return points;
+end
+
+
+function Perimeter.append_blacklist_file(self, event)
+ local blacklist = io.open(self.blacklist_file, 'a');
+ if not blacklist then
+ self.log:error('[', event.key, '/', event.sequence, '] PERIMETER_APPEND_BLACKLIST - could not open file: ', self.blacklist_file);
+ return false;
+ end
+
+ event.date = self:format_date(event.timestamp);
+
+ if self.blacklist_file_comment then
+ blacklist:write(self:expand_variables(self.blacklist_file_comment, event), '\n');
+ end
+
+ self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_APPEND_BLACKLIST - file: ', self.blacklist_file);
+ blacklist:write(self:expand_variables(self.blacklist_file_entry, event), '\n');
+ blacklist:close();
+end
+
+
+function Perimeter.execute_ban(self, event)
+ local command = self:expand_variables(self.ban_command, event);
+ self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_EXECUTE_BAN - command: ', command);
+ local result = os.execute(command);
+end
+
+function Perimeter.update_intruder(self, event)
+ require 'common.intruder';
+ local result = common.intruder.Intruder:new{ log = self.log, database = self.database }:update_blacklist(event);
+end
+
+
+function Perimeter.expand_variables(self, line, variables)
+ return (line:gsub('{([%a%d%._]+)}', function(captured)
+ return variables[captured] or '';
+ end))
+end
diff --git a/misc/freeswitch/scripts/common/sip_account.lua b/misc/freeswitch/scripts/common/sip_account.lua
index 8dd432b..d023f20 100644
--- a/misc/freeswitch/scripts/common/sip_account.lua
+++ b/misc/freeswitch/scripts/common/sip_account.lua
@@ -38,8 +38,12 @@ function SipAccount.find_by_sql(self, where)
`a`.`sip_accountable_id`, \
`a`.`hotdeskable`, \
`a`.`gs_node_id`, \
- `b`.`host` \
- FROM `sip_accounts` `a` JOIN `sip_domains` `b` ON `a`.`sip_domain_id` = `b`.`id` \
+ `b`.`host`, \
+ `c`.`sip_host`, \
+ `c`.`profile_name` \
+ FROM `sip_accounts` `a` \
+ JOIN `sip_domains` `b` ON `a`.`sip_domain_id` = `b`.`id` \
+ LEFT JOIN `sip_registrations` `c` ON `a`.`auth_name` = `c`.`sip_user` \
WHERE ' .. where .. ' LIMIT 1';
local sip_account = nil;
diff --git a/misc/freeswitch/scripts/common/str.lua b/misc/freeswitch/scripts/common/str.lua
index 793c191..72ff388 100644
--- a/misc/freeswitch/scripts/common/str.lua
+++ b/misc/freeswitch/scripts/common/str.lua
@@ -18,6 +18,23 @@ function try(array, arguments)
return result;
end
+
+function set(array, arguments, value)
+ local nop, arguments_count = arguments:gsub('%.', '');
+ local structure = array;
+ arguments:gsub('([^%.]+)', function(entry)
+ if arguments_count <= 0 then
+ structure[entry] = value;
+ elseif type(structure[entry]) == 'table' then
+ structure = structure[entry];
+ else
+ structure[entry] = {};
+ structure = structure[entry];
+ end
+ arguments_count = arguments_count - 1;
+ end);
+end
+
-- to number
function to_n(value)
value = tostring(value):gsub('[^%d%.%+%-]', '');
diff --git a/misc/freeswitch/scripts/configuration.lua b/misc/freeswitch/scripts/configuration.lua
index 062cf5d..75d0df3 100644
--- a/misc/freeswitch/scripts/configuration.lua
+++ b/misc/freeswitch/scripts/configuration.lua
@@ -63,7 +63,12 @@ function profile(database, sofia_ini, profile_name, index, domains, node_id)
require 'configuration.simple_xml'
local xml = configuration.simple_xml.SimpleXml:new();
- local parameters = sofia_ini['profile:' .. profile_name];
+ local profile_template = sofia_ini['profile'] or {};
+ local parameters = sofia_ini['profile:' .. profile_name] or {};
+
+ for key, value in pairs(profile_template) do
+ parameters[key] = parameters[key] or value;
+ end
if not parameters then
log:error('SOFIA_PROFILE ', index,' - name: ', profile_name, ' - no parameters');
@@ -134,9 +139,16 @@ function conf_sofia(database)
require 'configuration.sip'
local domains = configuration.sip.Sip:new{ log = log, database = database}:domains();
- sofia_profiles_xml = '';
+ local sofia_profiles = {};
for profile_name, index in pairs(sofia_ini.profiles) do
if tonumber(index) and tonumber(index) > 0 then
+ sofia_profiles[index] = profile_name;
+ end
+ end
+
+ local sofia_profiles_xml = '';
+ for index, profile_name in ipairs(sofia_profiles) do
+ if tonumber(index) and tonumber(index) > 0 then
sofia_profiles_xml = sofia_profiles_xml .. profile(database, sofia_ini, profile_name, tonumber(index), domains, local_node_id);
end
end
@@ -403,7 +415,7 @@ function directory_sip_account(database)
end
else
require 'common.sip_account'
- local sip_account = common.sip_account.SipAccount:new{ log = log, database = database}:find_by_auth_name(auth_name, domain);
+ local sip_account = common.sip_account.SipAccount:new{ log = log, database = database}:find_by_auth_name(auth_name);
require 'common.configuration_table'
local user_parameters = common.configuration_table.get(database, 'sip_accounts', 'parameters');
diff --git a/misc/freeswitch/scripts/dialplan/acd.lua b/misc/freeswitch/scripts/dialplan/acd.lua
index f4b298e..5ed8979 100644
--- a/misc/freeswitch/scripts/dialplan/acd.lua
+++ b/misc/freeswitch/scripts/dialplan/acd.lua
@@ -194,7 +194,7 @@ function AutomaticCallDistributor.agents_available(self, strategy)
local accounts = {}
self.database:query(sql_query, function(entry)
- if not entry.callstate then
+ if common.str.blank(entry.callstate) then
table.insert(accounts, entry);
end
end);
diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua
index ff4adc6..72503e5 100644
--- a/misc/freeswitch/scripts/dialplan/dialplan.lua
+++ b/misc/freeswitch/scripts/dialplan/dialplan.lua
@@ -350,10 +350,10 @@ function Dialplan.set_caller_picture(self, entry_id, entry_type, image)
require 'dialplan.user'
local user = dialplan.user.User:new{ log = self.log, database = self.database }:find_by_id(entry_id);
if user then
- self.caller:set_variable('sip_h_Call-Info', '<' .. self.user_image_url .. '/' .. tonumber(entry_id) .. '/snom_caller_picture_' .. tostring(user.record.image) .. '>;purpose=icon');
+ self.caller:export_variable('sip_h_Call-Info', '<' .. self.user_image_url .. '/' .. tonumber(entry_id) .. '/snom_caller_picture_' .. tostring(user.record.image) .. '>;purpose=icon');
end
elseif entry_type == 'phonebookentry' and image then
- self.caller:set_variable('sip_h_Call-Info', '<' .. self.phone_book_entry_image_url .. '/' .. tonumber(entry_id) .. '/snom_caller_picture_' .. tostring(image) .. '>;purpose=icon');
+ self.caller:export_variable('sip_h_Call-Info', '<' .. self.phone_book_entry_image_url .. '/' .. tonumber(entry_id) .. '/snom_caller_picture_' .. tostring(image) .. '>;purpose=icon');
end
end
@@ -445,6 +445,8 @@ function Dialplan.dial(self, destination)
send_ringing = ( self.send_ringing_to_gateways and self.caller.from_gateway ),
bypass_media_network = self.config.parameters.bypass_media_network,
update_callee_display = self.config.parameters.update_callee_display,
+ detect_dtmf_after_bridge_caller = self.detect_dtmf_after_bridge_caller,
+ detect_dtmf_after_bridge_callee = self.detect_dtmf_after_bridge_callee,
}
);
end
@@ -759,7 +761,7 @@ function Dialplan.switch(self, destination)
elseif not common.str.blank(destination.number) then
local result = { continue = false, code = 404, phrase = 'No route' }
- local clip_no_screening = common.str.try(caller, 'account.record.clip_no_screening');
+ local clip_no_screening = common.str.try(self.caller, 'account.record.clip_no_screening');
self.caller.caller_id_numbers = {}
if not common.str.blank(clip_no_screening) then
for index, number in ipairs(common.str.strip_to_a(clip_no_screening, ',')) do
@@ -814,11 +816,13 @@ function Dialplan.switch(self, destination)
self.caller:set_callee_id(destination.callee_id_number, destination.callee_id_name);
for index, route in ipairs(routes) do
- if route.endpoint_type == 'hangup' then
- return { continue = false, code = route.endpoint, phrase = route.phrase, cause = route.value }
+ if route.type == 'hangup' then
+ self.log:notice('SWITCH_HANGUP - code: ', route.code, ', phrase: ', route.phrase, ', cause: ', route.cause);
+ return { continue = false, code = route.code or '404', phrase = route.phrase, cause = route.cause }
end
- if route.endpoint_type == 'forward' then
- return { continue = true, call_forwarding = { number = route.value, service = 'route', type = 'phonenumber' }}
+ if route.type == 'forward' then
+ self.log:notice('SWITCH_CALL_FORWARDING - number: ', route.number);
+ return { continue = true, call_forwarding = { number = route.number, service = 'route', type = 'phonenumber' }}
end
for key, value in pairs(route) do
diff --git a/misc/freeswitch/scripts/dialplan/dtmf.lua b/misc/freeswitch/scripts/dialplan/dtmf.lua
new file mode 100644
index 0000000..4dbd35f
--- /dev/null
+++ b/misc/freeswitch/scripts/dialplan/dtmf.lua
@@ -0,0 +1,69 @@
+-- Gemeinschaft 5 module: dtmf class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+Dtmf = {}
+
+-- create dtmf object
+function Dtmf.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.class = 'Dtmf';
+ self.log = arg.log;
+ self.bleg = arg.bleg
+ self.digit_timeout = arg.digit_timeout or 5;
+ self.router = arg.router;
+
+ return object;
+end
+
+
+function Dtmf.detect(self, caller, sequence, digit, duration, calee)
+ local timestamp = os.time();
+ if timestamp - sequence.updated > self.digit_timeout then
+ sequence.digits = digit;
+ else
+ sequence.digits = sequence.digits .. digit;
+ end
+
+ caller.dtmf_digits = sequence.digits;
+
+ if calee then
+ self.log:debug('DTMF_RECEIVER callee - digit: [', digit, '][', duration, '], sequence: ', sequence.digits);
+ else
+ self.log:debug('DTMF_RECEIVER caller - digit: [', digit, '][', duration, '], sequence: ', sequence.digits);
+ end
+
+ local route = self.router:route_run('dtmf', true);
+ sequence.updated = timestamp;
+
+ if not route then
+ return;
+ end
+
+ if route.type == 'dialplanfunction' or route.type == 'phonenumber' or route.type == 'unknown' then
+ self:transfer(caller, route.destination_number, calee)
+ else
+ self.log:notice('DTMF_RECEIVER - unhandled destination: ', route.type, '=', route.id);
+ end
+end
+
+
+function Dtmf.transfer(self, caller, destination, calee)
+ require 'common.fapi'
+ local fapi = common.fapi.FApi:new{ log = log };
+ local callee_uuid = caller:to_s('bridge_to');
+
+ self.log:notice('DTMF_RECEIVER_TRANSFER - destination: ', destination, ', uuid: ', caller.uuid, ', callee_uuid: ', callee_uuid, ', callee_initiated: ', calee);
+ if calee then
+ caller:execute('transfer', destination);
+ fapi:execute('uuid_kill', callee_uuid);
+ else
+ fapi:execute('uuid_transfer', callee_uuid .. ' ' .. destination);
+ caller.session:hangup();
+ end
+end
diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua
index 2ca51c8..4430be1 100644
--- a/misc/freeswitch/scripts/dialplan/functions.lua
+++ b/misc/freeswitch/scripts/dialplan/functions.lua
@@ -111,6 +111,8 @@ function Functions.dialplan_function(self, caller, dialed_number)
result = "+" .. tostring(parameters[3]);
elseif fid == "hangup" then
result = self:hangup(caller, parameters[3], parameters[4]);
+ elseif fid == "park" then
+ result = self:park(caller, parameters[3]);
end
return result;
@@ -264,7 +266,7 @@ function Functions.account_node_change(self, caller)
-- resync caller phones
for index, phone_caller in ipairs(caller_phones) do
- local result = phone_caller:resync{ auth_name = caller_sip_account.auth_name, domain = caller.domain };
+ local result = phone_caller:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host };
self.log:info('NODE_CHANGE - resync phone - mac: ', phone_caller.record.mac_address, ', ip_address: ', phone_caller.record.ip_address, ', result: ', result);
end
@@ -302,6 +304,7 @@ function Functions.user_login(self, caller, number, pin)
if not caller_phone then
self.log:notice('LOGIN - caller phone not found or not hot-deskable');
+ local result = phone_class:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host };
return { continue = false, code = 403, phrase = 'Phone not hot-deskable', no_cdr = true }
end
@@ -374,13 +377,13 @@ function Functions.user_login(self, caller, number, pin)
-- resync destination phones
for index, phone_destination in ipairs(destination_phones) do
- local result = phone_destination:resync{ auth_name = destination_sip_account.auth_name, domain = caller.domain_local };
+ local result = phone_destination:resync{ auth_name = destination_sip_account.record.auth_name, domain = destination_sip_account.record.host };
self.log:info('LOGIN - resync destination phone - mac: ', phone_destination.record.mac_address, ', ip_address: ', phone_destination.record.ip_address, ', result: ', result);
end
-- resync caller phones
for index, phone_caller in ipairs(caller_phones) do
- local result = phone_caller:resync{ auth_name = caller_sip_account.auth_name, domain = caller.domain };
+ local result = phone_caller:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host };
self.log:info('LOGIN - resync caller phone - mac: ', phone_caller.record.mac_address, ', ip_address: ', phone_caller.record.ip_address, ', result: ', result);
end
@@ -409,8 +412,9 @@ function Functions.user_logout(self, caller)
local caller_phones = phone_class:find_all_hot_deskable_by_account(caller_sip_account.id);
- if caller_phones == 0 then
+ if #caller_phones == 0 then
self.log:notice('LOGOUT - caller phones not found or not hot-deskable');
+ local result = phone_class:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host };
return { continue = false, code = 403, phrase = 'Phone not hot-deskable', no_cdr = true }
end
@@ -426,7 +430,7 @@ function Functions.user_logout(self, caller)
-- resync caller phones
for index, phone_caller in ipairs(caller_phones) do
- local result = phone_caller:resync{ auth_name = caller_sip_account.auth_name, domain = caller.domain };
+ local result = phone_caller:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host };
self.log:info('LOGIN - resync caller phone - mac: ', phone_caller.record.mac_address, ', ip_address: ', phone_caller.record.ip_address, ', result: ', result);
end
@@ -909,3 +913,9 @@ function Functions.hangup(self, caller, code, phrase)
self.log:info("FUNCTION_HANGUP code: ", code, ', phrase: ', phrase);
return { continue = false, code = code, phrase = phrase:gsub('_', ' '), no_cdr = true }
end
+
+function Functions.park(self, caller, lot)
+ self.log:info("FUNCTION_PARK lot: ", lot);
+ caller:execute("valet_park", 'valet_lot ' .. lot);
+ return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
+end
diff --git a/misc/freeswitch/scripts/dialplan/hunt_group.lua b/misc/freeswitch/scripts/dialplan/hunt_group.lua
index 2c73bf8..fa3c05b 100644
--- a/misc/freeswitch/scripts/dialplan/hunt_group.lua
+++ b/misc/freeswitch/scripts/dialplan/hunt_group.lua
@@ -98,6 +98,18 @@ function HuntGroup.run(self, dialplan_object, caller, destination)
self.log:info('HUNTGROUP ', self.record.id, ' - name: ', self.record.name, ', strategy: ', self.record.strategy,', members: ', #hunt_group_members);
+ local clip_no_screening = common.str.try(caller, 'account.record.clip_no_screening');
+ caller.caller_id_numbers = {}
+ if not common.str.blank(clip_no_screening) then
+ for index, number in ipairs(common.str.strip_to_a(clip_no_screening, ',')) do
+ table.insert(caller.caller_id_numbers, number);
+ end
+ end
+ for index, number in ipairs(caller.caller_phone_numbers) do
+ table.insert(caller.caller_id_numbers, number);
+ end
+ self.log:info('CALLER_ID_NUMBERS - clir: ', caller.clir, ', numbers: ', table.concat(caller.caller_id_numbers, ','));
+
local save_destination = caller.destination;
local destinations = {}
@@ -172,6 +184,7 @@ function HuntGroup.run(self, dialplan_object, caller, destination)
self.log:info('HUNTGROUP ', self.record.id, ' - all members busy');
run_queue = false;
end
+ caller:sleep(500);
end
else
if forwarding_destination then
diff --git a/misc/freeswitch/scripts/dialplan/router.lua b/misc/freeswitch/scripts/dialplan/router.lua
index cdcb58b..bda80a7 100644
--- a/misc/freeswitch/scripts/dialplan/router.lua
+++ b/misc/freeswitch/scripts/dialplan/router.lua
@@ -18,11 +18,16 @@ function Router.new(self, arg)
self.routes = arg.routes or {};
self.caller = arg.caller;
self.variables = arg.variables or {};
+ self.routing_tables = {};
return object;
end
-function Router.read_table(self, table_name)
+function Router.read_table(self, table_name, force_reload)
+ if not force_reload and self.routing_tables[table_name] then
+ return self.routing_tables[table_name];
+ end
+
local routing_table = {};
local sql_query = 'SELECT * \
@@ -48,6 +53,8 @@ function Router.read_table(self, table_name)
});
end);
+ self.routing_tables[table_name] = routing_table;
+
return routing_table;
end
@@ -143,7 +150,7 @@ function Router.route_match(self, route)
if not common.str.blank(element.var_out) then
local command, variable_name = common.str.partition(element.var_out, ':');
if not command or not variable_name or command == 'var' then
- destination[element.var_out] = replacement;
+ common.str.set(destination, element.var_out, replacement);
elseif command == 'chv' then
destination.channel_variables[variable_name] = replacement;
elseif command == 'hdr' then
@@ -159,6 +166,7 @@ function Router.route_match(self, route)
end
if route_matches then
+ destination.number = destination.number or destination.destination_number;
return destination;
end;
diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua
index d1557e9..b56f1b2 100644
--- a/misc/freeswitch/scripts/dialplan/sip_call.lua
+++ b/misc/freeswitch/scripts/dialplan/sip_call.lua
@@ -95,39 +95,50 @@ function SipCall.fork(self, destinations, arg )
table.insert(origination_variables, 'ignore_display_updates=true');
end
- if not destination.node_local then
+ if not destination.node_local or destination.type == 'node' then
require 'common.node'
- local node = common.node.Node:new{ log = self.log, database = self.database }:find_by_id(destination.node_id);
- if node then
- table.insert(origination_variables, 'sip_h_X-GS_node_id=' .. self.caller.local_node_id);
- table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/gateway/' .. node.record.name .. '/' .. destination.number);
+ local node = nil;
+
+ if not destination.node_local then
+ node = common.node.Node:new{ log = self.log, database = self.database }:find_by_id(destination.node_id);
+ else
+ node = common.node.Node:new{ log = self.log, database = self.database }:find_by_id(destination.id);
end
- elseif destination.type == 'node' then
- local node = common.node.Node:new{ log = self.log, database = self.database }:find_by_id(destination.id);
if node then
table.insert(origination_variables, 'sip_h_X-GS_node_id=' .. self.caller.local_node_id);
+ table.insert(origination_variables, 'sip_h_X-GS_account_uuid=' .. tostring(self.caller.account_uuid));
+ table.insert(origination_variables, 'sip_h_X-GS_account_type=' .. tostring(self.caller.account_type));
+ table.insert(origination_variables, 'sip_h_X-GS_auth_account_type=' .. tostring(self.caller.auth_account_type));
+ table.insert(origination_variables, 'sip_h_X-GS_auth_account_uuid=' .. tostring(self.caller.auth_account_uuid));
+ table.insert(origination_variables, 'sip_h_X-GS_loop_count=' .. tostring(self.caller.loop_count));
table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/gateway/' .. node.record.name .. '/' .. destination.number);
end
elseif destination.type == 'sipaccount' then
local callee_id_params = '';
local sip_account = sip_account_class:find_by_id(destination.id);
- local call_waiting = self:call_waiting_busy(sip_account);
- if not call_waiting then
- destinations[index].numbers = sip_account:phone_numbers();
+ if not sip_account then
+ self.log:notice('FORK - sip_account not found - sip_account=', destination.id);
+ elseif common.str.blank(sip_account.record.profile_name) or common.str.blank(sip_account.record.sip_host) then
+ call_result = { code = 480, phrase = 'User offline', disposition = 'USER_NOT_REGISTERED' };
+ else
+ local call_waiting = self:call_waiting_busy(sip_account);
+ if not call_waiting then
+ destinations[index].numbers = sip_account:phone_numbers();
- if not arg.callee_id_name then
- table.insert(origination_variables, "effective_callee_id_name='" .. sip_account.record.caller_name .. "'");
- end
- if not arg.callee_id_number then
- table.insert(origination_variables, "effective_callee_id_number='" .. destination.number .. "'");
- end
- if destination.alert_info then
- table.insert(origination_variables, "alert_info='" .. destination.alert_info .. "'");
+ if not arg.callee_id_name then
+ table.insert(origination_variables, "effective_callee_id_name='" .. sip_account.record.caller_name .. "'");
+ end
+ if not arg.callee_id_number then
+ table.insert(origination_variables, "effective_callee_id_number='" .. destination.number .. "'");
+ end
+ if destination.alert_info then
+ table.insert(origination_variables, "alert_info='" .. destination.alert_info .. "'");
+ end
+ table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/' .. sip_account.record.profile_name .. '/' .. sip_account.record.auth_name .. '%' .. sip_account.record.sip_host);
+ else
+ some_destinations_busy = true;
+ call_result = { code = 486, phrase = 'User busy', disposition = 'USER_BUSY' };
end
- table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']user/' .. sip_account.record.auth_name);
- else
- some_destinations_busy = true;
- call_result = { code = 486, phrase = 'User busy', disposition = 'USER_BUSY' };
end
elseif destination.type == 'gateway' then
require 'common.gateway'
@@ -169,11 +180,6 @@ function SipCall.fork(self, destinations, arg )
end
self.caller:set_callee_id(arg.callee_id_number, arg.callee_id_name);
- self.caller:set_header('X-GS_account_uuid', self.caller.account_uuid);
- self.caller:set_header('X-GS_account_type', self.caller.account_type);
- self.caller:set_header('X-GS_auth_account_type', self.caller.auth_account_type);
- self.caller:set_header('X-GS_auth_account_uuid', self.caller.auth_account_uuid);
- self.caller:set_header('X-GS_loop_count', self.caller.loop_count);
self.caller:set_variable('call_timeout', arg.timeout );
self.log:info('FORK DIAL - destinations: ', #dial_strings, ', timeout: ', arg.timeout);
@@ -195,6 +201,12 @@ function SipCall.fork(self, destinations, arg )
fork_index = tonumber(session_callee:getVariable('gs_fork_index')) or 0;
local destination = destinations[fork_index];
+ if arg.detect_dtmf_after_bridge_caller then
+ session:execute('start_dtmf');
+ end
+ if arg.detect_dtmf_after_bridge_callee then
+ session_callee:execute('start_dtmf');
+ end
if arg.bypass_media_network then
local callee_uuid = session_callee:get_uuid();
@@ -226,10 +238,15 @@ function SipCall.fork(self, destinations, arg )
self.caller:set_variable('gs_destination_id', destination.id);
self.caller:set_variable('gs_destination_uuid', destination.uuid);
+ if arg.detect_dtmf_after_bridge_callee then
+ session_callee:setInputCallback('input_call_back_callee', 'session_callee');
+ end
+
self.log:info('FORK ', fork_index,
' BRIDGE - destination: ', destination.type, '=', destination.id, '/', destination.uuid,'@', destination.node_id,
', number: ', destination.number,
', dial_time: ', os.time() - start_time);
+
freeswitch.bridge(self.caller.session, session_callee);
self:wait_hangup(self.caller.session, session_callee);
end
diff --git a/misc/freeswitch/scripts/dialplan_default.lua b/misc/freeswitch/scripts/dialplan_default.lua
index 7caff57..8fb9057 100644
--- a/misc/freeswitch/scripts/dialplan_default.lua
+++ b/misc/freeswitch/scripts/dialplan_default.lua
@@ -8,13 +8,28 @@ function hangup_hook_caller(s, status, arg)
if tostring(status) == 'transfer' then
if start_caller and start_caller.destination then
log:info('CALL_TRANSFERRED - destination was: ', start_caller.destination.type, '=', start_caller.destination.id,', number: ' .. tostring(start_caller.destination.number) .. ', to: ' .. start_caller:to_s('sip_refer_to'));
- start_caller.auth_account = start_dialplan:object_find(start_caller.destination.type, start_caller.destination.id);
+ start_caller.auth_account = start_caller.dialplan:object_find(start_caller.destination.type, start_caller.destination.id);
start_caller.forwarding_number = start_caller.destination.number;
start_caller.forwarding_service = 'transfer';
end
end
end
+function input_call_back_caller(s, object_type, object_data, arg)
+ if object_type == 'dtmf' then
+ require 'dialplan.dtmf'
+ local dtmf = dialplan.dtmf.Dtmf:new{ log = log, router = dtmf_router }:detect(start_caller, start_caller.dtmf, object_data.digit, object_data.duration);
+ end
+end
+
+function input_call_back_callee(s, object_type, object_data, arg)
+ if object_type == 'dtmf' then
+ require 'dialplan.dtmf'
+ local dtmf = dialplan.dtmf.Dtmf:new{ log = log, router = dtmf_router }:detect(start_caller, start_caller.dtmf_callee, object_data.digit, object_data.duration, true);
+ end
+end
+
+
-- initialize logging
require 'common.log'
log = common.log.Log:new{ prefix = '### [' .. session:get_uuid() .. '] ' };
@@ -36,8 +51,17 @@ require 'dialplan.dialplan'
local start_dialplan = dialplan.dialplan.Dialplan:new{ log = log, caller = start_caller, database = database };
start_dialplan:configuration_read();
+start_caller.dialplan = start_dialplan;
start_caller.local_node_id = start_dialplan.node_id;
start_caller:init_channel_variables();
+start_caller.dtmf = {
+ updated = os.time(),
+ digits = '';
+};
+start_caller.dtmf_callee = {
+ updated = os.time(),
+ digits = '';
+};
if start_dialplan.config.parameters.dump_variables then
start_caller:execute('info', 'notice');
@@ -72,6 +96,17 @@ if start_caller.from_node then
else
start_destination = { type = 'unknown' }
start_caller.session:setHangupHook('hangup_hook_caller', 'destination_number');
+
+ require 'dialplan.router'
+ dtmf_router = dialplan.router.Router:new{ log = log, database = database, caller = start_caller, variables = start_caller };
+ start_dialplan.dtmf_detection = #dtmf_router:read_table('dtmf') > 0;
+
+ if start_dialplan.dtmf_detection then
+ start_dialplan.detect_dtmf_after_bridge_caller = true;
+ start_dialplan.detect_dtmf_after_bridge_callee = true;
+ start_caller.session:setInputCallback('input_call_back_caller', 'start_dialplan');
+ end
+
start_dialplan:run(start_destination);
end
diff --git a/misc/freeswitch/scripts/event/dump_variables.lua b/misc/freeswitch/scripts/event/dump_variables.lua
new file mode 100644
index 0000000..96eb8f7
--- /dev/null
+++ b/misc/freeswitch/scripts/event/dump_variables.lua
@@ -0,0 +1,52 @@
+-- Gemeinschaft 5 module: dump_variables event handler class
+-- (c) AMOOMA GmbH 2012-2013
+--
+
+module(...,package.seeall)
+
+
+function handler_class()
+ return DumpVariables
+end
+
+
+DumpVariables = {}
+
+
+function DumpVariables.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.log = arg.log;
+ self.class = 'DumpVariables'
+ self.dump_file = arg.file or '/var/log/freeswitch/variables';
+
+ return object;
+end
+
+
+function DumpVariables.event_handlers(self)
+ return { CHANNEL_CREATE = { [true] = self.channel_data } }
+end
+
+
+function DumpVariables.channel_data(self, event)
+ local sequence = event:getHeader('Event-Sequence');
+ local direction = event:getHeader('Call-Direction');
+
+ if not direction or direction ~= 'inbound' then
+ return;
+ end
+
+ local file = io.open(self.dump_file, 'w');
+ if not file then
+ self.log:error('[', event.sequence, '] DUMP_VARIABLES - could not open file for writing: ', self.dump_file);
+ return;
+ end
+
+ self.log:debug('[', event.sequence, '] DUMP_VARIABLES - dumping channel data to: ', self.dump_file);
+
+ file:write(event:serialize(), '\n');
+ file:close();
+end
diff --git a/misc/freeswitch/scripts/event/event.lua b/misc/freeswitch/scripts/event/event.lua
index 08d8bfe..652fc48 100644
--- a/misc/freeswitch/scripts/event/event.lua
+++ b/misc/freeswitch/scripts/event/event.lua
@@ -16,29 +16,40 @@ function EventManager.new(self, arg)
self.class = 'eventmanager'
self.database = arg.database;
self.domain = arg.domain;
+ self.consumer = arg.consumer;
return object;
end
function EventManager.register(self)
- self.consumer = freeswitch.EventConsumer('all');
+ if not self.consumer then
+ self.consumer = freeswitch.EventConsumer('all');
+ end
return (self.consumer ~= nil);
end
-function EventManager.load_event_modules(self)
- require 'common.configuration_table'
- self.config = common.configuration_table.get(self.database, 'events');
+function EventManager.load_event_modules(self, modules)
+ local event_modules = {};
+
+ for module_name, index in pairs(modules) do
+ if tonumber(index) and index > 0 then
+ event_modules[index] = module_name;
+ self.log:debug('[event] EVENT_MANAGER - enabled handler module: ', module_name);
+ else
+ self.log:debug('[event] EVENT_MANAGER - disabled handler module: ', module_name);
+ end
+ end
- return self.config.modules;
+ return event_modules;
end
function EventManager.load_event_handlers(self, event_modules)
event_handlers = {}
-
- for event_module_name, index in pairs(event_modules) do
+ for index, event_module_name in ipairs(event_modules) do
+ package.loaded['event.' .. event_module_name] = nil;
event_module = require('event.' .. event_module_name);
if event_module then
self.log:info('[event] EVENT_MANAGER - loading handler module: ', event_module_name);
@@ -71,8 +82,12 @@ end
function EventManager.run(self)
+ require 'common.configuration_table'
+ self.config = common.configuration_table.get(self.database, 'events');
+
+ local event_modules = self:load_event_modules(self.config.modules);
+ self.log:info('[event] EVENT_MANAGER_START - handler modules: ', #event_modules);
- local event_modules = self:load_event_modules();
local event_handlers = self:load_event_handlers(event_modules);
if not event_handlers then
@@ -104,4 +119,6 @@ function EventManager.run(self)
end
end
end
+
+ self.log:info('[event] EVENT_MANAGER_EXIT - action: ', freeswitch.getGlobalVariable('gs_event_manager'));
end
diff --git a/misc/freeswitch/scripts/event/perimeter.lua b/misc/freeswitch/scripts/event/perimeter.lua
deleted file mode 100644
index 5bbb032..0000000
--- a/misc/freeswitch/scripts/event/perimeter.lua
+++ /dev/null
@@ -1,107 +0,0 @@
--- Gemeinschaft 5 module: cdr event handler class
--- (c) AMOOMA GmbH 2012-2013
---
-
-module(...,package.seeall)
-
-
-function handler_class()
- return Perimeter
-end
-
-
-
-Perimeter = {}
-
-MALICIOUS_CONTACT_COUNT = 20;
-MALICIOUS_CONTACT_TIME_SPAN = 2;
-BAN_FUTILE = 2;
-
-function Perimeter.new(self, arg)
- arg = arg or {}
- object = arg.object or {}
- setmetatable(object, self);
- self.__index = self;
- self.log = arg.log;
- self.class = 'cdrsave'
- self.database = arg.database;
- self.domain = arg.domain;
-
- self.ip_address_table = {}
- self:init();
-
- return object;
-end
-
-
-function Perimeter.event_handlers(self)
- return { CUSTOM = { ['sofia::pre_register'] = self.sofia_pre_register } }
-end
-
-
-function Perimeter.init(self)
- require 'common.configuration_table';
- local config = common.configuration_table.get(self.database, 'perimeter');
- if config and config.general then
- self.malicious_contact_count = tonumber(config.general.malicious_contact_count) or MALICIOUS_CONTACT_COUNT;
- self.malicious_contact_time_span = tonumber(config.general.malicious_contact_time_span) or MALICIOUS_CONTACT_TIME_SPAN;
- self.ban_futile = tonumber(config.general.ban_futile) or BAN_FUTILE;
- self.execute = config.general.execute;
- end
-
- self.log:info('[perimeter] PERIMETER - setup perimeter defense - config: ', self.malicious_contact_count, '/', self.malicious_contact_time_span, ', execute: ', self.execute);
-end
-
-
-function Perimeter.sofia_pre_register(self, event)
- local ip_address = event:getHeader('network-ip');
- self:check_ip(ip_address);
-end
-
-
-function Perimeter.check_ip(self, ip_address)
- local event_time = os.time();
-
- if not self.ip_address_table[ip_address] then
- self.ip_address_table[ip_address] = { last_contact = event_time, contact_count = 0, start_stamp = event_time, banned = 0 }
- end
-
- local ip_record = self.ip_address_table[ip_address];
- ip_record.last_contact = event_time;
- ip_record.contact_count = ip_record.contact_count + 1;
-
- if ip_record.contact_count > MALICIOUS_CONTACT_COUNT then
- if (event_time - ip_record.start_stamp) <= MALICIOUS_CONTACT_TIME_SPAN then
- self.log:warning('[', ip_address, '] PERIMETER - too many registration attempts');
- ip_record.start_stamp = event_time;
- ip_record.contact_count = 0;
- if ip_record.banned < BAN_FUTILE then
- ip_record.banned = ip_record.banned + 1;
- self:ban_ip(ip_address);
- else
- self.log:error('[', ip_address, '] PERIMETER - ban futile');
- end
- end
- end
-end
-
-
-function Perimeter.ban_ip(self, ip_address)
- self.ip_address = ip_address;
-
- if self.execute then
- local command = self:expand_variables(self.execute);
- self.log:debug('[', ip_address, '] PERIMETER - execute: ', command);
- local result = os.execute(command);
- if tostring(result) == '0' then
- self.log:warning('[', ip_address, '] PERIMETER - IP banned');
- end
- end
-end
-
-
-function Perimeter.expand_variables(self, line)
- return (line:gsub('{([%a%d_-]+)}', function(captured)
- return self[captured];
- end))
-end
diff --git a/misc/freeswitch/scripts/event/perimeter_defense.lua b/misc/freeswitch/scripts/event/perimeter_defense.lua
new file mode 100644
index 0000000..acdfa8d
--- /dev/null
+++ b/misc/freeswitch/scripts/event/perimeter_defense.lua
@@ -0,0 +1,114 @@
+-- Gemeinschaft 5 module: perimeter defense event handler class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+function handler_class()
+ return PerimeterDefense
+end
+
+PerimeterDefense = {}
+
+function PerimeterDefense.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.log = arg.log;
+ self.class = 'perimeterdefense'
+ self.database = arg.database;
+ self.domain = arg.domain;
+
+ require 'common.perimeter';
+ self.perimeter = common.perimeter.Perimeter:new(arg);
+ self.perimeter:setup();
+
+ return object;
+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,
+ },
+ CHANNEL_HANGUP = { [true] = self.channel_hangup },
+ };
+end
+
+
+function PerimeterDefense.to_register_record(self, event, class)
+ return {
+ action = 'register',
+ class = class,
+ key = event:getHeader('network-ip'),
+ sequence = tonumber(event:getHeader('Event-Sequence')),
+ timestamp = tonumber(event:getHeader('Event-Date-Timestamp')),
+ received_ip = event:getHeader('network-ip'),
+ received_port = event:getHeader('network-port'),
+ from_user = event:getHeader('from-user'),
+ from_host = event:getHeader('from-host'),
+ to_user = event:getHeader('to-user'),
+ to_host = event:getHeader('to-host'),
+ user_agent = event:getHeader('user-agent'),
+ username = event:getHeader('username'),
+ realm = event:getHeader('realm'),
+ auth_result = event:getHeader('auth-result'),
+ contact = event:getHeader('contact'),
+ };
+end
+
+
+function PerimeterDefense.to_call_record(self, event, class)
+ return {
+ action = 'call',
+ class = class,
+ key = event:getHeader('Caller-Network-Addr'),
+ sequence = tonumber(event:getHeader('Event-Sequence')),
+ timestamp = tonumber(event:getHeader('Event-Date-Timestamp')),
+ received_ip = event:getHeader('Caller-Network-Addr'),
+ received_port = event:getHeader('variable_sip_network_port'),
+ hangup_cause = event:getHeader('Hangup-Cause'),
+ endpoint_disposition = event:getHeader('variable_endpoint_disposition'),
+ direction = event:getHeader('Call-Direction'),
+ destination_number = event:getHeader('Caller-Destination-Number');
+ caller_id_name = event:getHeader('Caller-Caller-ID-Name');
+ caller_id_number = event:getHeader('Caller-Caller-ID-Number');
+ from_user = event:getHeader('variable_sip_from_user'),
+ from_host = event:getHeader('variable_sip_from_host'),
+ to_user = event:getHeader('variable_sip_to_user'),
+ to_host = event:getHeader('variable_sip_to_host'),
+ req_user = event:getHeader('variable_sip_req_user'),
+ req_host = event:getHeader('variable_sip_req_host'),
+ user_agent = event:getHeader('variable_sip_user_agent'),
+ username = event:getHeader('Caller-Username'),
+ contact = event:getHeader('variable_sip_contact_uri'),
+ };
+end
+
+
+function PerimeterDefense.sofia_pre_register(self, event)
+ local record = self:to_register_record(event, 'pre_register');
+ self.perimeter:check(record);
+end
+
+
+function PerimeterDefense.sofia_register_attempt(self, event)
+ local record = self:to_register_record(event, 'register_attempt');
+ self.perimeter:check(record);
+end
+
+
+function PerimeterDefense.sofia_register_failure(self, event)
+ local record = self:to_register_record(event, 'register_failure');
+ self.perimeter:check(record);
+end
+
+
+function PerimeterDefense.channel_hangup(self, event)
+ local record = self:to_call_record(event, 'channel_hangup');
+ self.perimeter:check(record);
+end
diff --git a/misc/freeswitch/scripts/event_manager.lua b/misc/freeswitch/scripts/event_manager.lua
index 1e61baf..3991f8f 100644
--- a/misc/freeswitch/scripts/event_manager.lua
+++ b/misc/freeswitch/scripts/event_manager.lua
@@ -7,12 +7,12 @@ require "common.log"
local log = common.log.Log:new()
log.prefix = "#E# "
-log:info('[event] EVENT_MANAGER start');
+log:info('[event] EVENT_MANAGER_LOADER start');
require 'common.database'
local database = common.database.Database:new{ log = log }:connect();
if not database:connected() then
- log:error('[event] EVENT_MANAGER - cannot connect to Gemeinschaft database');
+ log:error('[event] EVENT_MANAGER_LOADER - cannot connect to Gemeinschaft database');
return;
end
@@ -23,16 +23,23 @@ local domain = '127.0.0.1';
if domains[1] then
domain = domains[1]['host'];
else
- log:error('[event] EVENT_MANAGER - No SIP domains found!');
+ log:error('[event] EVENT_MANAGER_LOADER - No SIP domains found!');
end
-require 'event.event'
-local event_manager = event.event.EventManager:new{ log = log, database = database, domain = domain }
-event_manager:run();
+local event_consumer = nil;
+freeswitch.setGlobalVariable('gs_event_manager', 'true');
+while freeswitch.getGlobalVariable('gs_event_manager') ~= 'false' do
+ package.loaded['event.event'] = nil;
+ local manager_class = require('event.event');
+ local event_manager = manager_class.EventManager:new{ log = log, database = database, domain = domain, consumer = event_consumer };
+ freeswitch.setGlobalVariable('gs_event_manager', 'true');
+ event_manager:run();
+ event_consumer = event_manager.consumer;
+end
-- ensure database handle is released on exit
if database then
database:release();
end
-log:info('[event] EVENT_MANAGER exit');
+log:info('[event] EVENT_MANAGER_LOADER exit');
diff --git a/misc/freeswitch/scripts/fax_daemon.lua b/misc/freeswitch/scripts/fax_daemon.lua
index 94d343a..0784890 100644
--- a/misc/freeswitch/scripts/fax_daemon.lua
+++ b/misc/freeswitch/scripts/fax_daemon.lua
@@ -5,38 +5,37 @@
local MAIN_LOOP_SLEEP_TIME = 30;
-- Set logger
-require "common.log"
+require 'common.log'
local log = common.log.Log:new()
-log.prefix = "### [faxdaemon] "
+log.prefix = '#F# [faxdaemon] '
-log:debug('Starting fax daemon');
+log:info('FAX_DAEMON start');
-local database = nil;
-local api = freeswitch.API();
+require 'common.database'
+local database = common.database.Database:new{ log = log }:connect();
+if not database:connected() then
+ log:error('FAX_DAEMON - cannot connect to Gemeinschaft database');
+ return;
+end
+local api = freeswitch.API();
+require 'dialplan.fax'
freeswitch.setGlobalVariable('gs_fax_daemon', 'true');
+
while freeswitch.getGlobalVariable("gs_fax_daemon") == 'true' do
- require 'common.database'
- local database = common.database.Database:new{ log = log }:connect();
-
- if not database:connected() then
- log:error("connection to Gemeinschaft database lost - retry in " .. MAIN_LOOP_SLEEP_TIME .. " seconds")
- else
- require 'dialplan.fax'
- local fax_documents = dialplan.fax.Fax:new{log=log, database=database}:queued_for_sending();
-
- for key, fax_document in pairs(fax_documents) do
- if table.getn(fax_document.destination_numbers) > 0 and tonumber(fax_document.retry_counter) > 0 then
- log:debug('FAX_DAEMON_LOOP - fax_document=', fax_document.id, '/', fax_document.uuid, ', number: ' .. fax_document.destination_numbers[1]);
- local result = api:executeString('luarun send_fax.lua ' .. fax_document.id);
- end
+ local fax_documents = dialplan.fax.Fax:new{log=log, database=database}:queued_for_sending();
+
+ for key, fax_document in pairs(fax_documents) do
+ if table.getn(fax_document.destination_numbers) > 0 and tonumber(fax_document.retry_counter) > 0 then
+ log:debug('FAX_DAEMON_LOOP - fax_document=', fax_document.id, '/', fax_document.uuid, ', number: ' .. fax_document.destination_numbers[1]);
+ local result = api:executeString('luarun send_fax.lua ' .. fax_document.id);
end
end
- database:release();
-
+
if freeswitch.getGlobalVariable("gs_fax_daemon") == 'true' then
freeswitch.msleep(MAIN_LOOP_SLEEP_TIME * 1000);
end
end
-log:debug('Exiting fax daemon');
+database:release();
+log:info('FAX_DAEMON exit');
diff --git a/misc/freeswitch/scripts/http_request.lua b/misc/freeswitch/scripts/http_request.lua
index 1d6f791..a74b4d8 100644
--- a/misc/freeswitch/scripts/http_request.lua
+++ b/misc/freeswitch/scripts/http_request.lua
@@ -29,7 +29,7 @@ end
local success, result, response_headers = http.request{url = url, headers = headers };
-if success then
+if success and tostring(result) == '200' then
log:debug('HTTP_REQUEST - url: ', url, ', auth: ', tostring(headers.Authorization ~= nil), ', result: ', result);
else
log:notice('HTTP_REQUEST - url: ', url, ', auth: ', tostring(headers.Authorization ~= nil), ', result: ', result);
diff --git a/misc/freeswitch/scripts/phones/phone.lua b/misc/freeswitch/scripts/phones/phone.lua
index 6da20f0..57997ba 100644
--- a/misc/freeswitch/scripts/phones/phone.lua
+++ b/misc/freeswitch/scripts/phones/phone.lua
@@ -115,8 +115,9 @@ end
function Phone.resync(self, arg)
if not self.model then
- self.log:notice('PHONE_RESYNC - unsupported phone model');
- return false;
+ self.log:notice('PHONE_RESYNC phone model not found - trying Snom resync');
+ require 'phones.snom'
+ return phones.snom.Snom:new{ log = self.log }:resync(arg);
end
arg.ip_address = arg.ip_address or self.record.ip_address;
diff --git a/misc/freeswitch/scripts/send_fax.lua b/misc/freeswitch/scripts/send_fax.lua
index 9b6ffce..4898cb8 100644
--- a/misc/freeswitch/scripts/send_fax.lua
+++ b/misc/freeswitch/scripts/send_fax.lua
@@ -6,9 +6,9 @@ local FAX_FILE_PATH = "/opt/GS5/public/uploads/fax_document/tiff/";
local FAX_ANSWERING_TIMEOUT = 20;
-- Set logger
-require "common.log"
+require 'common.log'
local log = common.log.Log:new()
-log.prefix = "### [sendfax] "
+log.prefix = '#F# [sendfax] '
local document_id = argv[1];
@@ -16,12 +16,12 @@ require 'common.database'
local database = common.database.Database:new{ log = log }:connect();
if not database:connected() then
- log:error('cannot connect to Gemeinschaft database');
+ log:error('FAX_SEND - cannot connect to Gemeinschaft database');
return
end
if not tonumber(document_id) then
- log:error('document id not specified');
+ log:error('FAX_SEND - document id not specified');
return
end
@@ -32,7 +32,7 @@ local fax_class = dialplan.fax.Fax:new(defaults);
local fax_document = fax_class:find_document_by_id(document_id);
if not fax_document then
- log:error('document ' .. document_id .. ' not found');
+ log:error('FAX_SEND - document ' .. document_id .. ' not found');
return
end
@@ -45,14 +45,14 @@ end
local fax_account = fax_class:find_by_id(fax_document.fax_account_id);
if not fax_account then
- log:error('fax account ' .. fax_document.fax_account_id .. ' not found');
+ log:error('FAX_SEND - fax account ' .. fax_document.fax_account_id .. ' not found');
return
end
local destination_number = fax_class:destination_number(document_id);
if not destination_number or tostring(destination_number) == '' then
- log:error('destination number not found');
+ log:error('FAX_SEND - destination number not found');
return
end
diff --git a/private_pub.ru b/private_pub.ru
deleted file mode 100644
index 2db4acf..0000000
--- a/private_pub.ru
+++ /dev/null
@@ -1,8 +0,0 @@
-# Run with: rackup private_pub.ru -s thin -E production
-require "bundler/setup"
-require "yaml"
-require "faye"
-require "private_pub"
-
-PrivatePub.load_config(File.expand_path("../config/private_pub.yml", __FILE__), ENV["RAILS_ENV"] || "development")
-run PrivatePub.faye_app
diff --git a/test/functional/backup_jobs_controller_test.rb b/test/functional/backup_jobs_controller_test.rb
new file mode 100644
index 0000000..17a0caf
--- /dev/null
+++ b/test/functional/backup_jobs_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class BackupJobsControllerTest < ActionController::TestCase
+ setup do
+ @backup_job = backup_jobs(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:backup_jobs)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create backup_job" do
+ assert_difference('BackupJob.count') do
+ post :create, backup_job: @backup_job.attributes
+ end
+
+ assert_redirected_to backup_job_path(assigns(:backup_job))
+ end
+
+ test "should show backup_job" do
+ get :show, id: @backup_job.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @backup_job.to_param
+ assert_response :success
+ end
+
+ test "should update backup_job" do
+ put :update, id: @backup_job.to_param, backup_job: @backup_job.attributes
+ assert_redirected_to backup_job_path(assigns(:backup_job))
+ end
+
+ test "should destroy backup_job" do
+ assert_difference('BackupJob.count', -1) do
+ delete :destroy, id: @backup_job.to_param
+ end
+
+ assert_redirected_to backup_jobs_path
+ end
+end
diff --git a/test/functional/intruders_controller_test.rb b/test/functional/intruders_controller_test.rb
new file mode 100644
index 0000000..0896022
--- /dev/null
+++ b/test/functional/intruders_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class IntrudersControllerTest < ActionController::TestCase
+ setup do
+ @intruder = intruders(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:intruders)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create intruder" do
+ assert_difference('Intruder.count') do
+ post :create, intruder: @intruder.attributes
+ end
+
+ assert_redirected_to intruder_path(assigns(:intruder))
+ end
+
+ test "should show intruder" do
+ get :show, id: @intruder.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @intruder.to_param
+ assert_response :success
+ end
+
+ test "should update intruder" do
+ put :update, id: @intruder.to_param, intruder: @intruder.attributes
+ assert_redirected_to intruder_path(assigns(:intruder))
+ end
+
+ test "should destroy intruder" do
+ assert_difference('Intruder.count', -1) do
+ delete :destroy, id: @intruder.to_param
+ end
+
+ assert_redirected_to intruders_path
+ end
+end
diff --git a/test/functional/system_messages_controller_test.rb b/test/functional/system_messages_controller_test.rb
deleted file mode 100644
index 2894cd3..0000000
--- a/test/functional/system_messages_controller_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'test_helper'
-
-class SystemMessagesControllerTest < ActionController::TestCase
- setup do
- @system_message = system_messages(:one)
- end
-
- test "should get index" do
- get :index
- assert_response :success
- assert_not_nil assigns(:system_messages)
- end
-
- test "should get new" do
- get :new
- assert_response :success
- end
-
- test "should create system_message" do
- assert_difference('SystemMessage.count') do
- post :create, system_message: @system_message.attributes
- end
-
- assert_redirected_to system_message_path(assigns(:system_message))
- end
-
- test "should show system_message" do
- get :show, id: @system_message.to_param
- assert_response :success
- end
-
- test "should get edit" do
- get :edit, id: @system_message.to_param
- assert_response :success
- end
-
- test "should update system_message" do
- put :update, id: @system_message.to_param, system_message: @system_message.attributes
- assert_redirected_to system_message_path(assigns(:system_message))
- end
-
- test "should destroy system_message" do
- assert_difference('SystemMessage.count', -1) do
- delete :destroy, id: @system_message.to_param
- end
-
- assert_redirected_to system_messages_path
- end
-end
diff --git a/test/unit/backup_job_test.rb b/test/unit/backup_job_test.rb
new file mode 100644
index 0000000..a63c219
--- /dev/null
+++ b/test/unit/backup_job_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class BackupJobTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert BackupJob.new.valid?
+ end
+end
diff --git a/test/unit/callthrough_test.rb b/test/unit/callthrough_test.rb
index 5764c0d..2e8cc56 100644
--- a/test/unit/callthrough_test.rb
+++ b/test/unit/callthrough_test.rb
@@ -12,7 +12,7 @@ class CallthroughTest < ActiveSupport::TestCase
@gemeinschaft_setup.country = Country.first
@gemeinschaft_setup.language = Language.first
- @current_user = @gemeinschaft_setup.build_user(
+ current_user = @gemeinschaft_setup.build_user(
:user_name => I18n.t('gemeinschaft_setups.initial_setup.admin_name'),
:male => true,
:email => 'admin@localhost',
@@ -52,18 +52,18 @@ class CallthroughTest < ActiveSupport::TestCase
@tenant.did_list = '02622-70648-x, 02622-706480'
@tenant.save
- @tenant.tenant_memberships.create(:user_id => @current_user.id)
- @current_user.update_attributes!(:current_tenant_id => @tenant.id)
+ @tenant.tenant_memberships.create(:user_id => current_user.id)
+ current_user.update_attributes!(:current_tenant_id => @tenant.id)
# The first user becomes a member of the 'admin' UserGroup
#
admin_group = @tenant.user_groups.create(:name => I18n.t('gemeinschaft_setups.initial_setup.admin_group_name'))
- admin_group.users << @current_user
+ admin_group.users << current_user
# User group
#
user_group = @tenant.user_groups.create(:name => I18n.t('gemeinschaft_setups.initial_setup.user_group_name'))
- user_group.users << @current_user
+ user_group.users << current_user
# Generate the internal_extensions
#
@@ -84,7 +84,7 @@ class CallthroughTest < ActiveSupport::TestCase
#
assert @gemeinschaft_setup.valid?
assert @sip_domain.valid?
- assert @current_user.valid?
+ assert current_user.valid?
assert @tenant.valid?
diff --git a/test/unit/intruder_test.rb b/test/unit/intruder_test.rb
new file mode 100644
index 0000000..f1b7963
--- /dev/null
+++ b/test/unit/intruder_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class IntruderTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert Intruder.new.valid?
+ end
+end
diff --git a/test/unit/system_message_test.rb b/test/unit/system_message_test.rb
deleted file mode 100644
index 0476ac8..0000000
--- a/test/unit/system_message_test.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require 'test_helper'
-
-class SystemMessageTest < ActiveSupport::TestCase
- # def test_should_be_valid
- # assert SystemMessage.new.valid?
- # end
-end