diff --git a/Gemfile b/Gemfile index 271636bed..871a3b305 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,8 @@ source 'http://rubygems.org' -gem 'rails', '3.2.14' - -# preparation for rails 4 -#gem 'rails', '4.0.0.rc1' -#gem 'rails-observers' -#gem 'activerecord-session_store' +gem 'rails', '4.0.0' +gem 'rails-observers' +gem 'activerecord-session_store' gem 'eco' @@ -19,10 +16,8 @@ gem 'json' group :assets do # preparation for rails 4 -# gem 'sass-rails', '~> 4.0.0.rc1' -# gem 'coffee-rails', '~> 4.0.0.rc1' - gem 'sass-rails', '~> 3.2.4' - gem 'coffee-rails', '~> 3.2.2' + gem 'sass-rails', '~> 4.0.0' + gem 'coffee-rails', '~> 4.0.0' gem 'uglifier' end @@ -76,6 +71,8 @@ gem 'em-websocket' # in production environments by default. group :development, :test do + gem 'test-unit' + gem 'sqlite3' # code coverage @@ -92,5 +89,4 @@ group :development, :test do # gem 'em-websocket-client' end -gem 'thin' -#gem 'puma' +gem 'puma' diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f146683fa..cf2233f11 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,8 +14,8 @@ class ApplicationController < ActionController::Base :mode_show_rendeder, :model_index_render - skip_filter :verify_authenticity_token - before_filter :log_request, :set_user, :session_update + skip_before_filter :verify_authenticity_token + before_filter :set_user, :session_update before_filter :cors_preflight_check after_filter :set_access_control_headers @@ -53,10 +53,6 @@ class ApplicationController < ActionController::Base Observer::Ticket::Notification.transaction end - def log_request - puts Time.now().to_s + ' ' + request.original_fullpath.to_s - end - # Finds the User with the ID stored in the session with the key # :current_user_id This is a common way to handle user login in # a Rails application; logging in sets the session value and @@ -99,7 +95,7 @@ class ApplicationController < ActionController::Base def authentication_check_only - puts 'authentication_check' + #puts 'authentication_check' session[:request_type] = 1 #puts params.inspect #puts session.inspect @@ -107,7 +103,7 @@ class ApplicationController < ActionController::Base # check http basic auth authenticate_with_http_basic do |username, password| - puts 'http basic auth check' + #puts 'http basic auth check' session[:request_type] = 2 userdata = User.authenticate( username, password ) @@ -261,7 +257,7 @@ class ApplicationController < ActionController::Base begin # create object - generic_object = object.new( object.param_cleanup(params) ) + generic_object = object.new( object.param_cleanup( params[object.to_app_model] ) ) # save object generic_object.save! @@ -270,6 +266,7 @@ class ApplicationController < ActionController::Base rescue Exception => e puts e.message.inspect logger.error e.message + logger.error e.backtrace.inspect render :json => { :error => e.message }, :status => :unprocessable_entity end end @@ -284,10 +281,11 @@ class ApplicationController < ActionController::Base generic_object = object.find( params[:id] ) # save object - generic_object.update_attributes!( object.param_cleanup(params) ) + generic_object.update_attributes!( object.param_cleanup( params[object.to_app_model] ) ) model_update_render_item(generic_object) rescue Exception => e logger.error e.message + logger.error e.backtrace.inspect render :json => { :error => e.message }, :status => :unprocessable_entity end end @@ -302,6 +300,7 @@ class ApplicationController < ActionController::Base model_destory_render_item() rescue Exception => e logger.error e.message + logger.error e.backtrace.inspect render :json => { :error => e.message }, :status => :unprocessable_entity end end @@ -315,6 +314,7 @@ class ApplicationController < ActionController::Base model_show_render_item(generic_object) rescue Exception => e logger.error e.message + logger.error e.backtrace.inspect render :json => { :error => e.message }, :status => :unprocessable_entity end end @@ -328,6 +328,7 @@ class ApplicationController < ActionController::Base model_index_render_result( generic_object ) rescue Exception => e logger.error e.message + logger.error e.backtrace.inspect render :json => { :error => e.message }, :status => :unprocessable_entity end end diff --git a/app/controllers/taskbar_controller.rb b/app/controllers/taskbar_controller.rb index 8b0f1cee7..92e3e53c1 100644 --- a/app/controllers/taskbar_controller.rb +++ b/app/controllers/taskbar_controller.rb @@ -18,7 +18,6 @@ class TaskbarController < ApplicationController end def create - params[:user_id] = current_user.id model_create_render(Taskbar,params) end @@ -26,7 +25,6 @@ class TaskbarController < ApplicationController taskbar = Taskbar.find( params[:id] ) return if !access(taskbar) - params[:user_id] = current_user.id taskbar.update_attributes!( Taskbar.param_cleanup(params) ) model_update_render_item(taskbar) end diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index ecd5a144f..fe1c5dc08 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -53,7 +53,7 @@ class TicketsController < ApplicationController if params[:article] form_id = params[:article][:form_id] params[:article].delete(:form_id) - @article = Ticket::Article.new( params[:article] ) + @article = Ticket::Article.new( Ticket::Article.param_validation( params[:article] ) ) @article.ticket_id = @ticket.id # find attachments in upload cache diff --git a/app/models/application_model.rb b/app/models/application_model.rb index b591d47f8..c8601c1d2 100644 --- a/app/models/application_model.rb +++ b/app/models/application_model.rb @@ -1,12 +1,9 @@ # Copyright (C) 2013-2013 Zammad Foundation, http://zammad-foundation.org/ -require 'cache' -require 'user_info' -require 'sessions' - class ApplicationModel < ActiveRecord::Base self.abstract_class = true + before_create :check_attributes_protected, :cache_delete, :fill_up_user_create before_create :cache_delete, :fill_up_user_create before_update :cache_delete_before, :fill_up_user_update before_destroy :cache_delete_before @@ -16,12 +13,11 @@ class ApplicationModel < ActiveRecord::Base @@import_class_list = ['Ticket', 'Ticket::Article', 'History', 'Ticket::State', 'Ticket::Priority', 'Group', 'User' ] - # for import of other objects, remove 'id' - def self.attributes_protected_by_default + def check_attributes_protected if Setting.get('import_mode') && @@import_class_list.include?( self.name.to_s ) - ['type'] + # do noting, use id as it is else - ['id','type'] + self[:id] = nil end end @@ -39,6 +35,10 @@ returns def self.param_cleanup(params) + if params == nil + raise "No params for #{self.to_s}!" + end + # only use object attributes data = {} self.new.attributes.each {|item| @@ -71,7 +71,9 @@ returns data.delete( :created_at ) data.delete( :updated_by_id ) data.delete( :created_by_id ) - + if data.respond_to?('permit!') + data.permit! + end data end diff --git a/app/models/sla.rb b/app/models/sla.rb index af26476e0..455589f78 100644 --- a/app/models/sla.rb +++ b/app/models/sla.rb @@ -1,7 +1,5 @@ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ -require 'cache' - class Sla < ApplicationModel store :condition store :data diff --git a/app/models/taskbar.rb b/app/models/taskbar.rb index c9cab98c4..fd4636739 100644 --- a/app/models/taskbar.rb +++ b/app/models/taskbar.rb @@ -3,11 +3,14 @@ class Taskbar < ApplicationModel store :state store :params - before_create :update_last_contact - before_update :update_last_contact + before_create :update_last_contact, :set_user + before_update :update_last_contact, :set_user private def update_last_contact self.last_contact = Time.now end + def set_user + self.user_id = UserInfo.current_user_id + end end diff --git a/app/models/ticket.rb b/app/models/ticket.rb index 3669c13ac..b27c4211c 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -1,8 +1,5 @@ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ -require 'time_calculation' -require 'sla' - class Ticket < ApplicationModel before_create :check_generate, :check_defaults before_update :check_defaults diff --git a/app/models/user.rb b/app/models/user.rb index b89a2aa88..d25505e69 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,9 +1,5 @@ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ -require 'sso' -require 'digest/sha2' -require 'organization' - class User < ApplicationModel include User::Assets extend User::Search diff --git a/config/application.rb b/config/application.rb index 660fa2180..9655249a6 100644 --- a/config/application.rb +++ b/config/application.rb @@ -16,7 +16,7 @@ module Zammad # -- all .rb files in that directory are automatically loaded. # Custom directories with classes and modules you want to be autoloadable. - config.autoload_paths += Dir["#{config.root}/lib/**/"] + config.autoload_paths += Dir["#{config.root}/lib/*", "#{config.root}/lib/**/"] # config.autoload_paths += %W(#{config.root}/lib) # Only load the plugins named here, in the order given (default is alphabetical). @@ -61,12 +61,6 @@ module Zammad # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql - # Enforce whitelist mode for mass assignment. - # This will create an empty whitelist of attributes available for mass-assignment for all models - # in your app. As such, your models will need to explicitly whitelist or blacklist accessible - # parameters by using an attr_accessible or attr_protected declaration. - # config.active_record.whitelist_attributes = true - # Enable the asset pipeline config.assets.enabled = true @@ -79,11 +73,5 @@ module Zammad # REST api path config.api_path = '/api/v1' - # Enable threaded mode - config.threadsafe! - - # catch all router files - config.paths['config/routes'] += Dir[Rails.root.join("config/routes/*.rb")] - end end diff --git a/config/environments/development.rb b/config/environments/development.rb index c9d05dbe1..32a81aad6 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -6,8 +6,8 @@ Zammad::Application.configure do # since you don't have to restart the web server when you make code changes. config.cache_classes = false - # Log error messages when you accidentally call methods on nil. - config.whiny_nils = true + # Do not eager load code on boot. + config.eager_load = false # Show full error reports and disable caching config.consider_all_requests_local = true @@ -19,15 +19,8 @@ Zammad::Application.configure do # Print deprecation notices to the Rails logger config.active_support.deprecation = :log - # Only use best-standards-support built into browsers - config.action_dispatch.best_standards_support = :builtin - - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - config.active_record.auto_explain_threshold_in_seconds = 0.5 + # Raise an error on page load if there are pending migrations + config.active_record.migration_error = :page_load # Do not compress assets config.assets.compress = false diff --git a/config/environments/production.rb b/config/environments/production.rb index 4ecfb86e5..e57a56520 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -4,6 +4,12 @@ Zammad::Application.configure do # Code is not reloaded between requests config.cache_classes = true + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both thread web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + # Full error reports are disabled and caching is turned on config.consider_all_requests_local = false config.action_controller.perform_caching = true @@ -14,14 +20,18 @@ Zammad::Application.configure do # Compress JavaScripts and CSS config.assets.compress = true + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = false # Generate digests for assets URLs config.assets.digest = true - # Defaults to Rails.root.join("public/assets") - # config.assets.manifest = YOUR_PATH + # Version of your assets, change this if you want to expire all your assets. + config.assets.version = '1.0' # Specifies the header that your server uses for sending files # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache @@ -32,6 +42,7 @@ Zammad::Application.configure do # See everything in the log (default is :info) # config.log_level = :debug + config.log_level = :info # Prepend all log lines with the following tags # config.log_tags = [ :subdomain, :uuid ] @@ -51,9 +62,6 @@ Zammad::Application.configure do # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false - # Enable threaded mode - # config.threadsafe! - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) config.i18n.fallbacks = true @@ -61,10 +69,12 @@ Zammad::Application.configure do # Send deprecation notices to registered listeners config.active_support.deprecation = :notify - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - # config.active_record.auto_explain_threshold_in_seconds = 0.5 + # Disable automatic flushing of the log to improve performance. + # config.autoflush_log = false # autoload on config.dependency_loading = true + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new end diff --git a/config/environments/test.rb b/config/environments/test.rb index f3e3b8f66..970488c3b 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -7,6 +7,11 @@ Zammad::Application.configure do # and recreated between test runs. Don't rely on the data there! config.cache_classes = true + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" @@ -15,9 +20,6 @@ Zammad::Application.configure do config.assets.compile = true config.assets.digest = true - # Log error messages when you accidentally call methods on nil - config.whiny_nils = true - # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = true @@ -30,9 +32,6 @@ Zammad::Application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - # Print deprecation notices to the stderr config.active_support.deprecation = :stderr diff --git a/config/environments/test_mysql.rb b/config/environments/test_mysql.rb index f3e3b8f66..37bab79d2 100644 --- a/config/environments/test_mysql.rb +++ b/config/environments/test_mysql.rb @@ -15,9 +15,6 @@ Zammad::Application.configure do config.assets.compile = true config.assets.digest = true - # Log error messages when you accidentally call methods on nil - config.whiny_nils = true - # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = true @@ -30,9 +27,6 @@ Zammad::Application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - # Print deprecation notices to the stderr config.active_support.deprecation = :stderr diff --git a/config/initializers/core_ext.rb b/config/initializers/core_ext.rb new file mode 100644 index 000000000..15097b71d --- /dev/null +++ b/config/initializers/core_ext.rb @@ -0,0 +1,6 @@ +# load all core_ext extentions +Dir["#{Rails.root}/lib/core_ext/*"].each {|file| + if File.file?(file) + require file + end +} diff --git a/config/routes.rb b/config/routes.rb index ecf3f32e4..58108ab4e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,4 +8,11 @@ Zammad::Application.routes.draw do # just remember to delete public/index.html. root :to => 'init#index', :via => :get + # load routes from external files + dir = File.expand_path('../', __FILE__) + files = Dir.glob( "#{dir}/routes/*.rb" ) + for file in files + require file + end + end \ No newline at end of file diff --git a/lib/core_ext/class.rb b/lib/core_ext/class.rb new file mode 100644 index 000000000..b1c3c4695 --- /dev/null +++ b/lib/core_ext/class.rb @@ -0,0 +1,10 @@ +class Class + def to_app_model + camel_cased_word = self.to_s + camel_cased_word.gsub(/::/, '_'). + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + end +end diff --git a/lib/core_ext/string.rb b/lib/core_ext/string.rb new file mode 100644 index 000000000..1a293d2fe --- /dev/null +++ b/lib/core_ext/string.rb @@ -0,0 +1,22 @@ +class String + def message_quote + quote = self.split("\n") + body_quote = '' + quote.each do |line| + body_quote = body_quote + '> ' + line + "\n" + end + body_quote + end + def word_wrap(*args) + options = args.extract_options! + unless args.blank? + options[:line_width] = args[0] || 82 + end + options.reverse_merge!(:line_width => 82) + + lines = self + lines.split("\n").collect do |line| + line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line + end * "\n" + end +end diff --git a/lib/notification_factory.rb b/lib/notification_factory.rb index 1126a5b11..35d908a4d 100644 --- a/lib/notification_factory.rb +++ b/lib/notification_factory.rb @@ -1,26 +1,3 @@ -class String - def message_quote - quote = self.split("\n") - body_quote = '' - quote.each do |line| - body_quote = body_quote + '> ' + line + "\n" - end - body_quote - end - def word_wrap(*args) - options = args.extract_options! - unless args.blank? - options[:line_width] = args[0] || 82 - end - options.reverse_merge!(:line_width => 82) - - lines = self - lines.split("\n").collect do |line| - line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line - end * "\n" - end -end - module NotificationFactory def self.build(data) @@ -85,4 +62,4 @@ module NotificationFactory true ) end -end \ No newline at end of file +end diff --git a/script/local_browser_tests.sh b/script/local_browser_tests.sh index 80db77f1b..c5e16d82e 100755 --- a/script/local_browser_tests.sh +++ b/script/local_browser_tests.sh @@ -9,7 +9,8 @@ while true; do esac done -export RAILS_ENV=test +#export RAILS_ENV=test +export RAILS_ENV=production bundle install @@ -17,25 +18,32 @@ rm -rf tmp/cache/file_store rm -f public/assets/*.css* rm -f public/assets/*.js* -#rake assets:precompile +rake assets:precompile rake db:drop rake db:create rake db:migrate rake db:seed -thin stop +#thin stop +pumactl --pidfile tmp/pids/puma.pid stop script/websocket-server.rb stop -thin start --threaded -d -p 4444 +#thin start --threaded -d -p 4444 +pumactl start --pidfile tmp/pids/puma.pid -d -p 4444 -e $RAILS_ENV script/websocket-server.rb start -d sleep 15 +#export REMOTE_URL='http://medenhofer:765d0dd4-994b-4e15-9f89-13f3aedeb462@ondemand.saucelabs.com:80/wd/hub' BROWSER_OS='Windows 2012' BROWSER_VERSION=20 BROWSER=firefox + rake test:browser["BROWSER_URL=http://localhost:4444"] +#rake test:browser["BROWSER_URL=http://192.168.178.20:4444"] + script/websocket-server.rb stop -thin stop +pumactl --pidfile tmp/pids/puma.pid stop +#thin stop rm -f public/assets/*.css* rm -f public/assets/*.js*