contao 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,7 @@ module TechnoGate
14
14
 
15
15
  FileUtils.mkdir_p File.dirname(global_config_path)
16
16
  File.open global_config_path, 'w' do |config|
17
- config.write YAML.dump(Contao::Application.default_global_config)
17
+ config.write YAML.dump(default_global_config)
18
18
  end
19
19
 
20
20
  message = <<-EOS.gsub(/ [ ]+/, '').gsub("\n", ' ').chop
@@ -25,7 +25,11 @@ module TechnoGate
25
25
  end
26
26
 
27
27
  def global_config_path
28
- Contao::Application.instance.global_config_path
28
+ Contao::Application.global_config_path
29
+ end
30
+
31
+ def default_global_config(options = {})
32
+ Contao::Application.send(:default_global_config, options)
29
33
  end
30
34
  end
31
35
  end
@@ -0,0 +1,54 @@
1
+ require 'contao/generators/base'
2
+
3
+ module TechnoGate
4
+ module Contao
5
+ module Generators
6
+ class ContaoInitializer < Base
7
+
8
+ TEMPLATE = File.expand_path '../../templates/contao_initializer.rb.erb', __FILE__
9
+
10
+ def generate
11
+ config = build_config
12
+ File.open initializer_path, 'w' do |f|
13
+ f.write ERB.new(File.read TEMPLATE).result(binding)
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def initializer_path
20
+ "#{project_path}/config/initializers/contao.rb"
21
+ end
22
+
23
+ def build_config
24
+ config = ActiveSupport::OrderedOptions.new
25
+
26
+ config.install_password = install_password
27
+ config.encryption_key = encryption_key
28
+ config.admin_email = global.admin_email
29
+ config.time_zone = global.time_zone
30
+ config.smtp_enabled = global.smtp.enabled
31
+ config.smtp_host = global.smtp.host
32
+ config.smtp_user = global.smtp.user
33
+ config.smtp_pass = global.smtp.pass
34
+ config.smtp_ssl = global.smtp.ssl
35
+ config.smtp_port = global.smtp.port
36
+
37
+ config
38
+ end
39
+
40
+ def global
41
+ Contao::Application.config.contao.global
42
+ end
43
+
44
+ def install_password
45
+ Password.create(global.install_password).to_s
46
+ end
47
+
48
+ def encryption_key
49
+ SecureRandom.hex 16
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,40 @@
1
+ require 'digest/sha1'
2
+ require 'securerandom'
3
+
4
+ module TechnoGate
5
+ module Contao
6
+ class Password
7
+ SALT_SIZE = 23
8
+
9
+ def initialize(password_hash)
10
+ password_hash.split(':').tap do |p|
11
+ @password_hash = p[0]
12
+ @salt = p[1]
13
+ end
14
+ end
15
+
16
+ def self.create(password)
17
+ salt = generate_salt
18
+ new "#{hash_password(password, salt)}:#{salt}"
19
+ end
20
+
21
+ def to_s
22
+ "#{@password_hash}:#{@salt}"
23
+ end
24
+
25
+ protected
26
+
27
+ def self.hash_password(password, salt)
28
+ Digest::SHA1.hexdigest "#{salt}#{password}"
29
+ end
30
+
31
+ def self.generate_salt
32
+ random[0...SALT_SIZE]
33
+ end
34
+
35
+ def self.random(length = 64)
36
+ SecureRandom.hex length
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,32 @@
1
+ require 'rails/railtie'
2
+
3
+ module TechnoGate
4
+ module Contao
5
+ class Railtie < Rails::Railtie
6
+ railtie_name :contao
7
+
8
+ rake_tasks do
9
+ Dir["#{File.expand_path '../../tasks', __FILE__}/**/*.rake"].each {|f| load f}
10
+ end
11
+
12
+ initializer 'load_contao_configurations' do
13
+ TechnoGate::Contao::Application.load_global_config!
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ class Rails::Railtie::Configuration
20
+ def contao
21
+ @contao_configuration ||= default_contao_configuration
22
+ end
23
+
24
+ private
25
+
26
+ def default_contao_configuration
27
+ cc = ActiveSupport::OrderedOptions.new
28
+ cc.smtp = ActiveSupport::OrderedOptions.new
29
+ cc.smtp.enabled = false
30
+ cc
31
+ end
32
+ end
@@ -0,0 +1,41 @@
1
+ # This initializer is used by Rake and Capistrano to help generating the
2
+ # localconfig.php file, it stores basically the encrypted install password,
3
+ # the encryption_key and the SMTP credentials if SMTP is enabled
4
+
5
+ module ContaoTemplate
6
+ class Application < Rails::Application
7
+ # The install password is used by /contao/install.php page
8
+ config.contao.install_password = '<%= config.install_password %>'
9
+
10
+ # The encryption key is used by extensions
11
+ config.contao.encryption_key = '<%= config.encryption_key %>'
12
+
13
+ # The admin email
14
+ config.admin_email = '<%= config.admin_email %>'
15
+
16
+ # The time zone
17
+ config.time_zone = '<%= config.time_zone %>'
18
+
19
+ # SMTP Configuration
20
+ # Configure contao to use an SMTP server
21
+
22
+ # Enable SMTP ?
23
+ config.contao.smtp.enabled = <%= config.smtp_enabled %>
24
+ <% if config.smtp_enabled %>
25
+ # SMTP Host
26
+ config.contao.smtp.host = '<%= config.smtp_host %>'
27
+
28
+ # SMTP User
29
+ config.contao.smtp.user = '<%= config.smtp_user %>'
30
+
31
+ # SMTP Pass
32
+ config.contao.smtp.pass = '<%= config.smtp_pass %>'
33
+
34
+ # SMTP SSL
35
+ config.contao.smtp.ssl = <%= config.smtp_ssl %>
36
+
37
+ # SMTP Port
38
+ config.contao.smtp.port = <%= config.smtp_port %>
39
+ <% end %>
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module Contao
2
- VERSION = '0.5.2'
2
+ VERSION = '0.6.0'
3
3
  end
data/lib/contao.rb CHANGED
@@ -3,12 +3,10 @@ require 'contao/core_ext/object'
3
3
  require 'singleton'
4
4
  require 'ostruct'
5
5
 
6
- module TechnoGate
7
- module Contao
8
- end
9
- end
6
+ # Utilities
7
+ require 'contao/password'
10
8
 
11
9
  # Contao
12
10
  require 'contao/application'
13
11
  require 'contao/notifier'
14
- require 'contao/railtie' if defined?(Rails)
12
+ require 'contao/railties' if defined?(::Rails)
@@ -12,7 +12,7 @@ def ask(what, options = {})
12
12
  q.validate = validate
13
13
  q.responses[:not_valid] = what
14
14
  unless echo
15
- q.echo = "*"
15
+ q.echo = '*'
16
16
  end
17
17
  end
18
18
  end
@@ -22,7 +22,7 @@ def public_path
22
22
  end
23
23
 
24
24
  namespace :contao do
25
- desc "Link all contao files"
25
+ desc 'Link all contao files'
26
26
  task :bootstrap do
27
27
  TechnoGate::Contao::Application.linkify
28
28
 
@@ -35,22 +35,22 @@ namespace :contao do
35
35
  Rake::Task['assets:precompile'].invoke if Rails.env.production?
36
36
  Rake::Task['contao:fix_permissions'].invoke
37
37
 
38
- TechnoGate::Contao::Notifier.notify("The contao folder has been bootstraped, Good Luck.", title: "Contao Bootstrap")
38
+ TechnoGate::Contao::Notifier.notify 'The contao folder has been bootstraped, Good Luck.'
39
39
  end
40
40
 
41
41
  desc 'Apply Patches'
42
42
  task :apply_patches do
43
43
  path = File.expand_path "../../../contao_patches/#{Rails.env}", __FILE__
44
44
  Dir["#{path}/**/*.patch"].each do |patch|
45
- TechnoGate::Contao::Notifier.notify("Applying patch #{File.basename patch}", title: "Contao Bootstrap")
45
+ TechnoGate::Contao::Notifier.notify("Applying patch #{File.basename patch}")
46
46
  result = system <<-CMD
47
47
  cd #{public_path}
48
48
  patch -Nfp1 -i #{patch} --no-backup-if-mismatch
49
49
  CMD
50
50
 
51
51
  if !result
52
- TechnoGate::Contao::Notifier.notify("Patch #{File.basename patch} failed to apply", title: "Contao Bootstrap")
53
- abort "Please fix patches before bootstrapping"
52
+ TechnoGate::Contao::Notifier.notify("Patch #{File.basename patch} failed to apply")
53
+ abort 'Please fix patches before bootstrapping'
54
54
  end
55
55
  end
56
56
  end
@@ -82,47 +82,43 @@ namespace :contao do
82
82
 
83
83
  FileUtils.chmod 0666, public_path.join('sitemap.xml')
84
84
 
85
- TechnoGate::Contao::Notifier.notify("The contao folder's permissions has been fixed.", title: "Contao Bootstrap")
85
+ TechnoGate::Contao::Notifier.notify 'The permissions of the contao folder has been fixed'
86
+ end
87
+
88
+ desc 'Generate an initializer'
89
+ task :generate_initializer do
90
+ require 'contao/generators/contao_initializer'
91
+
92
+ TechnoGate::Contao::Generators::ContaoInitializer.new(path: Rails.root).generate
93
+
94
+ TechnoGate::Contao::Notifier.notify 'The contao initializer has been generated'
86
95
  end
87
96
 
88
97
  desc "Generate the localconfig.php"
89
- task :generate_localconfig do
98
+ task :generate_localconfig => :environment do
90
99
  require 'active_support/core_ext/object/blank'
91
- config = TechnoGate::Contao::Application.config.contao_global_config
92
-
93
- if !config || config.install_password.blank? || config.encryption_key.blank?
94
- message = <<-EOS
95
- You did not set the install password, and the encryption key in your
96
- #{ENV['HOME']}/.contao/config.yml, I cannot generate a localconfig
97
- since the required configuration keys are missing.
98
- EOS
99
- message.gsub!(/ [ ]+/, ' ').gsub!(/\n/, '').gsub!(/^ /, '')
100
- TechnoGate::Contao::Notifier.warn(message, title: "Contao Bootstrap")
101
- else
102
- config = config.clone
103
- config.application_name = TechnoGate::Contao::Application.name
104
-
105
- config.db_server_app = 'mysql'
106
- config.db_hostname = config.mysql.host
107
- config.db_port = config.mysql.port
108
- config.db_username = config.mysql.user
109
- config.db_password = config.mysql.pass
110
- config.db_database = TechnoGate::Contao::Application.name
111
-
112
- localconfig_template = Rails.root.join 'config/examples/localconfig.php.erb'
113
- localconfig_path = public_path.join 'system/config/localconfig.php'
114
-
115
- localconfig = ERB.new(File.read(localconfig_template)).result(binding)
116
- File.open(localconfig_path, 'w') {|f| f.write localconfig }
117
-
118
- TechnoGate::Contao::Notifier.notify("The configuration file localconfig.php was generated successfully.", title: "Contao Bootstrap")
119
- end
100
+ config = Rails.application.config.contao.dup
101
+
102
+ config.db_server_app = 'mysql'
103
+ config.db_hostname = config.global.mysql.host
104
+ config.db_port = config.global.mysql.port
105
+ config.db_username = config.global.mysql.user
106
+ config.db_password = config.global.mysql.pass
107
+ config.db_database = config.application_name
108
+
109
+ localconfig_template = Rails.root.join 'config/examples/localconfig.php.erb'
110
+ localconfig_path = public_path.join 'system/config/localconfig.php'
111
+
112
+ localconfig = ERB.new(File.read(localconfig_template), nil, '-').result(binding)
113
+ File.open(localconfig_path, 'w') {|f| f.write localconfig }
114
+
115
+ TechnoGate::Contao::Notifier.notify 'The configuration file localconfig.php was generated successfully.'
120
116
  end
121
117
 
122
118
  desc "Generate the htaccess file"
123
119
  task :generate_htaccess do
124
120
  FileUtils.cp public_path.join('.htaccess.default'), public_path.join('.htaccess')
125
121
 
126
- TechnoGate::Contao::Notifier.notify("The .htaccess was successfully generated.", title: "Contao Bootstrap")
122
+ TechnoGate::Contao::Notifier.notify 'The .htaccess was successfully generated'
127
123
  end
128
124
  end
@@ -3,29 +3,29 @@ require 'spec_helper'
3
3
  module TechnoGate
4
4
  module Contao
5
5
  describe Application, :fakefs do
6
- subject { Contao::Application.instance }
6
+ subject { Contao::Application }
7
7
  let(:klass) { Contao::Application }
8
8
 
9
9
  before :each do
10
10
  stub_filesystem!(:global_config => {'install_password' => 'some install password'})
11
- subject.send :parse_global_config
11
+ subject.load_global_config!
12
12
  end
13
13
 
14
14
  describe "Global Config" do
15
15
 
16
16
  it "should parse the global config file if the file exists" do
17
- subject.config.contao_global_config.should_not be_empty
17
+ subject.config.contao.global.should_not be_empty
18
18
  end
19
19
 
20
20
  it "should correctly parse the global config" do
21
- subject.config.contao_global_config.install_password.should == 'some install password'
21
+ subject.config.contao.global.install_password.should == 'some install password'
22
22
  end
23
23
  end
24
24
 
25
25
  describe '#linkify' do
26
26
  it "should call #exhaustive_list_of_files_to_link" do
27
27
  subject.should_receive(:exhaustive_list_of_files_to_link).with(
28
- Rails.root.join(Rails.application.config.contao_path),
28
+ Rails.root.join(Rails.application.config.contao.path),
29
29
  Rails.public_path
30
30
  ).once.and_return []
31
31
 
@@ -62,7 +62,7 @@ module TechnoGate
62
62
  describe "without it being set in the configuration" do
63
63
  before :each do
64
64
  Rails.config.tap do |config|
65
- config.application_name = nil
65
+ config.contao.application_name = nil
66
66
  end
67
67
  end
68
68
 
@@ -78,7 +78,7 @@ module TechnoGate
78
78
  describe "with it being set in the configuration" do
79
79
  before :each do
80
80
  Rails.config.tap do |config|
81
- config.application_name = 'my_super_awesome_project'
81
+ config.contao.application_name = 'my_super_awesome_project'
82
82
  end
83
83
  end
84
84
 
@@ -6,8 +6,9 @@ module TechnoGate
6
6
  module Generators
7
7
  describe Application do
8
8
  let(:klass) { Application }
9
+
9
10
  subject {
10
- Application.new path: @path
11
+ klass.new path: @path
11
12
  }
12
13
 
13
14
  before :each do
@@ -64,7 +65,7 @@ module TechnoGate
64
65
  subject.send :rename_project
65
66
 
66
67
  File.read('/root/my_awesome_project/config/application.rb').should =~
67
- /config\.application_name\s+=\s+'my_awesome_project'/
68
+ /config\.contao\.application_name\s+=\s+'my_awesome_project'/
68
69
  end
69
70
  end
70
71
 
@@ -40,7 +40,7 @@ module TechnoGate
40
40
  subject.generate
41
41
 
42
42
  File.read("#{ENV['HOME']}/.contao/config.yml").should ==
43
- YAML.dump(Contao::Application.default_global_config)
43
+ YAML.dump(subject.send :default_global_config)
44
44
  end
45
45
 
46
46
  it "should call the Notifier" do
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'contao/generators/contao_initializer.rb'
3
+
4
+ module TechnoGate
5
+ module Contao
6
+ module Generators
7
+ describe ContaoInitializer, :fakefs => true do
8
+ let(:klass) { ContaoInitializer }
9
+
10
+ subject {
11
+ klass.new path: @path
12
+ }
13
+
14
+ before :each do
15
+ @path = '/root/my_awesome_project'
16
+
17
+ stub_filesystem! :global_config => {
18
+ 'admin_email' => 'test@example.com',
19
+ 'time_zone' => 'Europe/Paris',
20
+ 'smtp' => {
21
+ 'enabled' => true,
22
+ 'host' => 'localhost',
23
+ 'user' => 'myuser',
24
+ 'pass' => 'mypass',
25
+ 'ssl' => true,
26
+ 'port' => 465,
27
+ },
28
+ }
29
+
30
+ Contao::Application.send :load_global_config!
31
+ end
32
+
33
+ it_should_behave_like "Generator"
34
+
35
+ describe '#generate' do
36
+ before :each do
37
+ FakeFS.deactivate!
38
+ template = File.read ContaoInitializer::TEMPLATE
39
+ FakeFS.activate!
40
+ FileUtils.mkdir_p File.dirname(ContaoInitializer::TEMPLATE)
41
+ File.open ContaoInitializer::TEMPLATE, 'w' do |f|
42
+ f.write template
43
+ end
44
+ end
45
+
46
+ it 'should generate an initializer file' do
47
+ subject.generate
48
+ File.exists?('/root/my_awesome_project/config/initializers/contao.rb').should be_true
49
+ end
50
+ end
51
+
52
+ describe '#build_config' do
53
+ it 'should build a config variable for the template' do
54
+ Password.any_instance.stub(:to_s).and_return 'encrypted_password'
55
+ SecureRandom.stub(:hex).and_return 'e626cd6b8fd219b3e1803dc59620d972'
56
+
57
+ config = subject.send :build_config
58
+ config.install_password.should == 'encrypted_password'
59
+ config.encryption_key.should == 'e626cd6b8fd219b3e1803dc59620d972'
60
+ config.admin_email.should == 'test@example.com'
61
+ config.time_zone.should == 'Europe/Paris'
62
+ config.smtp_host.should == 'localhost'
63
+ config.smtp_user.should == 'myuser'
64
+ config.smtp_pass.should == 'mypass'
65
+ config.smtp_port.should == 465
66
+ config.smtp_enabled.should be_true
67
+ config.smtp_ssl.should be_true
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ module TechnoGate
4
+ module Contao
5
+ describe Password do
6
+ let(:clear_password) { 'password' }
7
+ let(:password) { '52c938dedcdc146d0a3f5fef834e9881be343d6c' }
8
+ let(:salt) { '537a4e714483674274a2b07' }
9
+ let(:password_hash) { "#{password}:#{salt}" }
10
+
11
+ describe 'class methods' do
12
+ subject { Password }
13
+
14
+ describe '#create' do
15
+
16
+ it { should respond_to :create }
17
+
18
+ it 'should return an instance of Password' do
19
+ subject.create(clear_password).should be_instance_of Password
20
+ end
21
+
22
+ it 'should return an instance with @password_hash and @salt set' do
23
+ p = subject.create clear_password
24
+ p.instance_variable_get(:@password_hash).should_not be_nil
25
+ p.instance_variable_get(:@salt).should_not be_nil
26
+ end
27
+
28
+ it 'should split the password_hash into instance variables' do
29
+ Password.should_receive(:generate_salt).and_return salt
30
+
31
+ p = subject.create clear_password
32
+ p.instance_variable_get(:@password_hash).should == password
33
+ p.instance_variable_get(:@salt).should == salt
34
+ end
35
+ end
36
+
37
+ describe '#generate_salt' do
38
+ it { should respond_to :generate_salt }
39
+
40
+ it 'should return a salt' do
41
+ subject.send(:generate_salt).should_not be_nil
42
+ end
43
+
44
+ it 'should be of the size of SALT_SIZE' do
45
+ subject.send(:generate_salt).size.should == Password::SALT_SIZE
46
+ end
47
+ end
48
+
49
+ describe '#random' do
50
+ it {should respond_to :random}
51
+
52
+ it 'should return a random string' do
53
+ subject.send(:random).should_not be_nil
54
+ end
55
+
56
+ it 'should honor the requested length' do
57
+ subject.send(:random, 14).size.should == 28
58
+ end
59
+
60
+ it 'should be 128 chars by default' do
61
+ subject.send(:random).size.should == 128
62
+ end
63
+
64
+ it 'should be a string' do
65
+ subject.send(:random).should be_instance_of String
66
+ end
67
+ end
68
+ end
69
+
70
+ describe 'initialization' do
71
+ subject { Password.new password_hash }
72
+
73
+ it 'should split the password_hash into instance variables' do
74
+ subject.instance_variable_get(:@password_hash).should == password
75
+ subject.instance_variable_get(:@salt).should == salt
76
+ end
77
+ end
78
+
79
+ describe 'instance methods' do
80
+ subject { Password.new password_hash }
81
+
82
+ describe 'to_s' do
83
+ it 'should return the password_hash' do
84
+ subject.to_s.should == password_hash
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
data/spec/spec_helper.rb CHANGED
@@ -21,15 +21,15 @@ RSpec.configure do |c|
21
21
  c.include FakeFS::SpecHelpers, :fakefs
22
22
 
23
23
  c.before :each do
24
- Rails.env = 'development'
25
- Rails.root = @root = '/root/my_awesome_project'
24
+ Rails.env = 'development'
25
+ Rails.root = '/root/my_awesome_project'
26
26
 
27
- Rails.config.tap do |config|
28
- config.contao_path = 'contao'
27
+ Rails.application.config.tap do |config|
28
+ config.contao.path = 'contao'
29
29
  end
30
30
 
31
31
  silence_warnings do
32
- TechnoGate::Contao::UI = stub('Guard UI').as_null_object
32
+ TechnoGate::Contao::UI = stub('UI').as_null_object
33
33
  end
34
34
  end
35
35
  end
@@ -2,6 +2,7 @@ def stub_filesystem!(options = {})
2
2
  [
3
3
 
4
4
  '/root/my_awesome_project/config',
5
+ '/root/my_awesome_project/config/initializers',
5
6
  '/root/my_awesome_project/app/assets/javascripts',
6
7
  '/root/my_awesome_project/app/assets/stylesheets',
7
8
  '/root/my_awesome_project/app/assets/images',
@@ -24,12 +25,11 @@ def stub_filesystem!(options = {})
24
25
  end
25
26
 
26
27
  def stub_global_config_file!(config = {})
27
- config = TechnoGate::Contao::Application.default_global_config(
28
- 'install_password' => 'f0fb33dcebe5753f053b882bb49faefe7384f22e:7305d1f250f3481bac35f2839a2a4fd6',
29
- 'encryption_key' => 'e626cd6b8fd219b3e1803dc59620d972'
28
+ condig = TechnoGate::Contao::Application.send(:default_global_config,
29
+ 'install_password' => 'password'
30
30
  ).merge(config)
31
31
 
32
- config_file = TechnoGate::Contao::Application.instance.global_config_path
32
+ config_file = "#{ENV['HOME']}/.contao/config.yml"
33
33
 
34
34
  FileUtils.mkdir_p File.dirname(config_file)
35
35
  File.open(config_file, 'w') do |file|
@@ -59,7 +59,7 @@ module ContaoTemplate
59
59
  # -- all .rb files in that directory are automatically loaded.
60
60
 
61
61
  # The application name
62
- config.application_name = '#{application_name}'
62
+ config.contao.application_name = '#{application_name}'
63
63
 
64
64
  # Custom directories with classes and modules you want to be autoloadable.
65
65
  # config.autoload_paths += %W(\#{config.root}/extras)
@@ -80,7 +80,7 @@ module ContaoTemplate
80
80
  config.assets.version = '1.0'
81
81
 
82
82
  # Contao configurations
83
- config.contao_path = 'contao'
83
+ config.contao.path = 'contao'
84
84
  end
85
85
  end
86
86
  EOS
@@ -0,0 +1,18 @@
1
+ require 'pry'
2
+
3
+ begin
4
+ require 'binding_of_caller'
5
+ rescue LoadError
6
+ end
7
+
8
+ def pry_it
9
+ FakeFS.deactivate! if example.metadata[:fakefs]
10
+
11
+ if binding.respond_to? :of_caller
12
+ binding.of_caller(1).pry
13
+ else
14
+ binding.pry
15
+ end
16
+
17
+ FakeFS.activate! if example.metadata[:fakefs]
18
+ end