From 065859b90cc5ef403b8f47bd5394b343e556cc4d Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 23 Mar 2016 21:48:52 +0100 Subject: upgrade: remove references to RestClient CouchRest > 1.2 does not use RestClient anymore. So we should not try to catch its errors. --- lib/extensions/couchrest.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/extensions/couchrest.rb b/lib/extensions/couchrest.rb index cc041e0..6967980 100644 --- a/lib/extensions/couchrest.rb +++ b/lib/extensions/couchrest.rb @@ -81,7 +81,7 @@ module CouchRest class ModelRailtie config.action_dispatch.rescue_responses.merge!( 'CouchRest::Model::DocumentNotFound' => :not_found, - 'RestClient::ResourceNotFound' => :not_found + 'CouchRest::NotFound' => :not_found ) end end -- cgit v1.2.3 From 00fba5114ae2c6176c88ff0ea152576c5bff657d Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 25 Mar 2016 11:06:55 +0100 Subject: upgrade: {File,Dir}.exists? -> exist? exists? is deprecated in ruby 2.1 --- lib/extensions/couchrest.rb | 2 +- lib/gemfile_tools.rb | 4 ++-- lib/tasks/i18n.rake | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/extensions/couchrest.rb b/lib/extensions/couchrest.rb index 6967980..4578926 100644 --- a/lib/extensions/couchrest.rb +++ b/lib/extensions/couchrest.rb @@ -69,7 +69,7 @@ module CouchRest def prepare_directory(dir = '') dir = Rails.root + 'tmp' + 'designs' + dir - Dir.mkdir(dir) unless Dir.exists?(dir) + Dir.mkdir(dir) unless Dir.exist?(dir) return dir end diff --git a/lib/gemfile_tools.rb b/lib/gemfile_tools.rb index dce2448..d1c00dc 100644 --- a/lib/gemfile_tools.rb +++ b/lib/gemfile_tools.rb @@ -68,7 +68,7 @@ def local_config empty_hash.default_proc = proc{|h, k| h.key?(k.to_s) ? h[k.to_s] : nil} ["defaults.yml", "config.yml"].inject(empty_hash.dup) {|config, file| filepath = File.join(File.expand_path("../../config", __FILE__), file) - if File.exists?(filepath) + if File.exist?(filepath) new_config = YAML.load_file(filepath) ['development', 'test','production'].each do |env| config[env] ||= empty_hash.dup @@ -87,7 +87,7 @@ end # or nil if not actually a gem directory # def gem_info(gem_dir) - if Dir.exists?(gem_dir) + if Dir.exist?(gem_dir) gemspec = Dir["#{gem_dir}/*.gemspec"] if gemspec.any? gem_name = File.basename(gemspec.first).sub(/\.gemspec$/,'') diff --git a/lib/tasks/i18n.rake b/lib/tasks/i18n.rake index 6ffbb23..1034211 100644 --- a/lib/tasks/i18n.rake +++ b/lib/tasks/i18n.rake @@ -63,7 +63,7 @@ namespace :i18n do desc "pull translations from transifex" task :download do Dir.chdir('config/') do - if !File.exists?('transifex.netrc') + if !File.exist?('transifex.netrc') puts "In order to download translations, you need a config/transifex.netrc file." puts "For example:" puts "machine www.transifex.com login yourusername password yourpassword" -- cgit v1.2.3 From f20ecdfb249128ba79da069407dce32f6f7e2fca Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 20 May 2016 11:47:38 +0200 Subject: include engine tests in default test --- lib/tasks/test.rake | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/tasks/test.rake b/lib/tasks/test.rake index d96b625..9859729 100644 --- a/lib/tasks/test.rake +++ b/lib/tasks/test.rake @@ -1,10 +1,15 @@ namespace :test do - [:units, :functionals, :integration].each do |type| - Rails::SubTestTask.new(type => "test:prepare") do |t| - t.libs << "test" - subdir = type.to_s.singularize - t.pattern = "engines/*/test/#{subdir}/**/*_test.rb" + namespace :engines do + [:units, :functionals, :integration].each do |type| + desc "Test engine #{type}" + Rails::TestTask.new(type => "test:prepare") do |t| + t.libs << "test" + subdir = type.to_s.singularize + t.pattern = "engines/*/test/#{subdir}/**/*_test.rb" + end + Rake::Task["test:#{type}"].enhance ["test:engines:#{type}"] + Rake::Task["test"].enhance ["test:engines:#{type}"] end end -- cgit v1.2.3 From 638acc59a241e141cf0fc9ccbf4e3c5578b98f0c Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 4 Jul 2016 20:19:21 +0200 Subject: Fix db:migrate and similar tasks We saw errors from duplicate loading of LocalEmail and LoginFormatValidation. The latter resulted in a crash. In an attempt to ensure all subclasses of Couchrest::Model::Base are loaded Couchrest::Model::Utils::Migrate requires all files in app/models. We have an extension that does the same for the engines. During this process LoginFormatValidation and LocalEmail were autoloaded when 'identity' was required. Afterwards they were required again. It looks like rails' autoload mechanism does not play nicely with require. So to make sure they are not autoloaded first move the concerns and helper classes into the lib directory and require them explicitly. --- lib/email.rb | 31 +++++++++++++++++++ lib/local_email.rb | 67 ++++++++++++++++++++++++++++++++++++++++++ lib/login_format_validation.rb | 21 +++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 lib/email.rb create mode 100644 lib/local_email.rb create mode 100644 lib/login_format_validation.rb (limited to 'lib') diff --git a/lib/email.rb b/lib/email.rb new file mode 100644 index 0000000..4090275 --- /dev/null +++ b/lib/email.rb @@ -0,0 +1,31 @@ +class Email < String + include ActiveModel::Validations + + validates :email, + :format => { + :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/, #local part of email is case-sensitive, so allow uppercase letter. + :message => "needs to be a valid email address" + } + + # Make sure we can call Email.new(nil) and get an invalid email address + def initialize(s) + super(s.to_s) + end + + def to_partial_path + "emails/email" + end + + def to_param + to_s + end + + def email + self + end + + def handle + self.split('@').first + end + +end diff --git a/lib/local_email.rb b/lib/local_email.rb new file mode 100644 index 0000000..7c592e1 --- /dev/null +++ b/lib/local_email.rb @@ -0,0 +1,67 @@ +require 'email' +class LocalEmail < Email + + BLACKLIST_FROM_RFC2142 = [ + 'postmaster', 'hostmaster', 'domainadmin', 'webmaster', 'www', + 'abuse', 'noc', 'security', 'usenet', 'news', 'uucp', + 'ftp', 'sales', 'marketing', 'support', 'info' + ] + + def self.domain + APP_CONFIG[:domain] + end + + validates :email, + :format => { + :with => /@#{domain}\Z/i, + :message => "needs to end in @#{domain}" + } + + validate :handle_allowed + + def initialize(s) + super + append_domain_if_needed + end + + def to_key + [handle] + end + + def domain + LocalEmail.domain + end + + protected + + def append_domain_if_needed + unless self.index('@') + self << '@' + domain + end + end + + def handle_allowed + errors.add(:handle, "is reserved.") if handle_reserved? + end + + def handle_reserved? + # *ARRAY in a case statement tests if ARRAY includes the handle. + case handle + when *APP_CONFIG[:handle_blacklist] + true + when *APP_CONFIG[:handle_whitelist] + false + when *BLACKLIST_FROM_RFC2142 + true + else + handle_in_passwd? + end + end + + def handle_in_passwd? + Etc.getpwnam(handle).present? + rescue ArgumentError + # handle was not found + return false + end +end diff --git a/lib/login_format_validation.rb b/lib/login_format_validation.rb new file mode 100644 index 0000000..c1fcf70 --- /dev/null +++ b/lib/login_format_validation.rb @@ -0,0 +1,21 @@ +module LoginFormatValidation + extend ActiveSupport::Concern + + #TODO: Probably will replace this. Playing with using it for aliases too, but won't want it connected to login field. + + included do + # Have multiple regular expression validations so we can get specific error messages: + validates :login, + :format => { :with => /\A.{2,}\z/, + :message => "Must have at least two characters"} + validates :login, + :format => { :with => /\A[a-z\d_\.-]+\z/, + :message => "Only lowercase letters, digits, . - and _ allowed."} + validates :login, + :format => { :with => /\A[a-z].*\z/, + :message => "Must begin with a lowercase letter"} + validates :login, + :format => { :with => /\A.*[a-z\d]\z/, + :message => "Must end with a letter or digit"} + end +end -- cgit v1.2.3 From b4ff3b959d4dd6a7561ac3be063a43619c0bd89c Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 12 Aug 2016 11:34:01 +0200 Subject: move temporary_user into lib - fix load issue We already did the same for other concerns. The way we load models for couchrest migrations does not work well with concerns in the model directory as they will be loaded twice. --- lib/temporary_user.rb | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 lib/temporary_user.rb (limited to 'lib') diff --git a/lib/temporary_user.rb b/lib/temporary_user.rb new file mode 100644 index 0000000..2afae15 --- /dev/null +++ b/lib/temporary_user.rb @@ -0,0 +1,93 @@ +# +# For users with login '*test_user*', we don't want to store these documents in +# the main users db. This is because we create and destroy a lot of test +# users. This weirdness of using a different db for some users breaks a lot of +# things, such as associations. However, this is OK for now since we don't need +# those for running the frequent nagios tests. +# +# This module is included in user.rb. This will only work if it is included +# after designs are defined, otherwise, the design definition will overwrite +# find_by_login(). +# + +module TemporaryUser + extend ActiveSupport::Concern + include CouchRest::Model::DatabaseMethod + + USER_DB = 'users' + TMP_USER_DB = 'tmp_users' + TMP_LOGIN = 'tmp_user' # created and deleted frequently + TEST_LOGIN = 'test_user' # created, rarely deleted + + included do + use_database_method :db_name + + # since the original find_by_login is dynamically created with + # instance_eval, it appears that we also need to use instance eval to + # override it. + instance_eval <<-EOS, __FILE__, __LINE__ + 1 + def find_by_login(*args) + if args.grep(/^#{TMP_LOGIN}/).any? + by_login.database(tmp_database).key(*args).first() + else + by_login.key(*args).first() + end + end + EOS + end + + module ClassMethods + def get(id, db = database) + super(id, db) || super(id, tmp_database) + end + alias :find :get + + # calls db_name(TMP_LOGIN), then creates a CouchRest::Database + # from the name + def tmp_database + choose_database(TMP_LOGIN) + end + + def db_name(login=nil) + if !login.nil? && login.include?(TMP_LOGIN) + TMP_USER_DB + else + USER_DB + end + end + + # create the tmp db if it doesn't exist. + # requires admin access. + def create_tmp_database! + design_doc.sync!(tmp_database.tap{|db|db.create!}) + end + + def is_tmp?(login) + !login.nil? && login =~ /^#{TMP_LOGIN}/ + end + + def is_test?(login) + !login.nil? && (login =~ /^#{TMP_LOGIN}/ || login =~ /^#{TEST_LOGIN}/) + end + end + + # + # this gets called each and every time a User object needs to + # access the database. + # + def db_name + self.class.db_name(self.login) + end + + # returns true if this User instance is stored in tmp db. + def is_tmp? + self.class.is_tmp?(self.login) + end + + # returns true if this user is used for testing purposes + # (either a temporary or long lived) + def is_test? + self.class.is_test?(self.login) + end + +end -- cgit v1.2.3 From f0d2f44ea3babdafc793856082d8c532b05187ae Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 12 Aug 2016 11:59:05 +0200 Subject: [db] remove DatabaseMethod import from TemporaryUser It was causing 404s on initializing the database with db:migrate. DatabaseMethods rewrite of #database does not call prepare_database and thus does not create the database when needed. DatabaseMethod is also quite a bit too much for a model that has two databases that can be memoized easily. There's no way to have a separate database instance per record. --- lib/temporary_user.rb | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) (limited to 'lib') diff --git a/lib/temporary_user.rb b/lib/temporary_user.rb index 2afae15..e41add5 100644 --- a/lib/temporary_user.rb +++ b/lib/temporary_user.rb @@ -12,16 +12,12 @@ module TemporaryUser extend ActiveSupport::Concern - include CouchRest::Model::DatabaseMethod - USER_DB = 'users' TMP_USER_DB = 'tmp_users' TMP_LOGIN = 'tmp_user' # created and deleted frequently TEST_LOGIN = 'test_user' # created, rarely deleted included do - use_database_method :db_name - # since the original find_by_login is dynamically created with # instance_eval, it appears that we also need to use instance eval to # override it. @@ -45,15 +41,7 @@ module TemporaryUser # calls db_name(TMP_LOGIN), then creates a CouchRest::Database # from the name def tmp_database - choose_database(TMP_LOGIN) - end - - def db_name(login=nil) - if !login.nil? && login.include?(TMP_LOGIN) - TMP_USER_DB - else - USER_DB - end + @tmp_database ||= prepare_database TMP_USER_DB end # create the tmp db if it doesn't exist. @@ -71,12 +59,12 @@ module TemporaryUser end end - # - # this gets called each and every time a User object needs to - # access the database. - # - def db_name - self.class.db_name(self.login) + def database + if login.present? && login.include?(TMP_LOGIN) + self.class.tmp_database + else + self.class.database + end end # returns true if this User instance is stored in tmp db. -- cgit v1.2.3 From 8fbe70729da1d308a118c930e8f938837484a61c Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 12 Aug 2016 17:26:51 +0200 Subject: [db] def database on users instead of use_database use_database affects all uses of prepare_database - so also the one in tmp_database. In order to avoid that we do not use_database but just overwrite the database method itself. --- lib/temporary_user.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/temporary_user.rb b/lib/temporary_user.rb index e41add5..d0db1c4 100644 --- a/lib/temporary_user.rb +++ b/lib/temporary_user.rb @@ -13,6 +13,7 @@ module TemporaryUser extend ActiveSupport::Concern + USER_DB = 'users' TMP_USER_DB = 'tmp_users' TMP_LOGIN = 'tmp_user' # created and deleted frequently TEST_LOGIN = 'test_user' # created, rarely deleted @@ -38,12 +39,15 @@ module TemporaryUser end alias :find :get - # calls db_name(TMP_LOGIN), then creates a CouchRest::Database - # from the name + def database + @database ||= prepare_database USER_DB + end + def tmp_database @tmp_database ||= prepare_database TMP_USER_DB end + # create the tmp db if it doesn't exist. # requires admin access. def create_tmp_database! -- cgit v1.2.3