diff --git a/Gemfile b/Gemfile index ff38129..0b58ac9 100644 --- a/Gemfile +++ b/Gemfile @@ -2,21 +2,5 @@ source "http://rubygems.org" gem 'adhearsion', :git => 'git://github.com/adhearsion/adhearsion.git', :branch => :develop -# Specify your gem's dependencies in ahn-asterisk.gemspec -gemspec - -source :rubygems - -group :development do - gem 'guard' - gem 'guard-rspec' - if RUBY_PLATFORM =~ /darwin/ - #gem 'growl_notify' - gem 'growl' - gem 'rb-fsevent' - else - gem 'rb-inotify', :require => false - #gem 'rb-fchange', :require => false - end -end - +# Specify your gem's dependencies in ahn-ldap.gemspec +gemspec \ No newline at end of file diff --git a/README.md b/README.md index 14db847..121a80e 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,56 @@ -# Getting started +ahn-ldap +======== -*ahn-ldap* is an Adhearsion plugin that allows AHN configuration via LDAP. +ahn-ldap is an Adhearsion Plugin providing LDAP connectivity. -# Install +Features +-------- -``` -gem install ahn-ldap -``` +* FIXME (list of features and unsolved problems) + +Requirements +------------ + +* Adhearsion 2.0+ -If you include the dependency in your application Gemfile, that should be enough as Adhearsion loads the Bundler environment. +Install +------- -If you use a gemspec or have just added it to your gems folder, include the line below in the script/ahn file: +Add `ahn-ldap` to your Adhearsion app's Gemfile. + +Configuration +------------- + +In your Adhearsion app configuration file, add the following values: ```ruby -require 'adhearsion' -require 'adhearsion/cli_commands' -require 'ahn-ldap' +Adhearsion.config do |config| + config.ahn_ldap.host = "valid-host" + config.ahn_ldap.port = "valid-port".to_i # 389 by default + config.ahn_ldap.base = "valid-ldap-base" + config.ahn_ldap.bind_dn = "valid-ldap-binding" + config.ahn_ldap.allallow_anonymous = true # false + config.ahn_ldap.try_sasl = true # false +end ``` -# Note on Patches/Pull Requests +Links +----- +* [Source](https://github.com/adhearsion/ahn-ldap) +* [Documentation](http://rdoc.info/github/adhearsion/ahn-ldap/master/frames) +* [Bug Tracker](https://github.com/adhearsion/ahn-ldap/issues) + +Note on Patches/Pull Requests +----------------------------- * Fork the project. * Make your feature addition or bug fix. * Add tests for it. This is important so I don't break it in a future version unintentionally. * Commit, do not mess with rakefile, version, or history. -* If you want to have your own version, that is fine but bump version in a commit by itself so I can ignore when I pull + * If you want to have your own version, that is fine but bump version in a commit by itself so I can ignore when I pull * Send me a pull request. Bonus points for topic branches. -# Copyright +Copyright +--------- -Check [License file](https://github.com/adhearsion/ahn-ldap/blob/master/LICENSE) +Check [License file](https://github.com/adhearsion/ahn-ldap/blob/master/LICENSE) \ No newline at end of file diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..53702fc --- /dev/null +++ b/Rakefile @@ -0,0 +1,16 @@ +require "bundler/gem_tasks" + +require "bundler/setup" + + +task :default => :spec + +require 'rspec/core' +require 'rspec/core/rake_task' + +RSpec::Core::RakeTask.new(:spec) do |spec| + spec.pattern = 'spec/**/*_spec.rb' + spec.rspec_opts = '--colour --format doc' +end + +task :default => :spec \ No newline at end of file diff --git a/ahn-ldap.gemspec b/ahn-ldap.gemspec index 45b35bd..e5cb586 100644 --- a/ahn-ldap.gemspec +++ b/ahn-ldap.gemspec @@ -5,8 +5,8 @@ require "ahn_ldap/version" Gem::Specification.new do |s| s.name = "ahn-ldap" s.version = AhnLDAP::VERSION - s.authors = ["Taylor Carpenter"] - s.email = ["tcarpenter@mojolingo.com"] + s.authors = ["Taylor Carpenter", "Juan de Bravo", "Ben Langfeld"] + s.email = ["tcarpenter@mojolingo.com", "juandebravo@gmail.com", "ben@langfeld.me"] s.homepage = "http://adhearsion.com" s.summary = %q{LDAP configuration for Adhearsion} s.description = %q{An Adhearsion Plugin providing LDAP configurability} @@ -20,15 +20,8 @@ Gem::Specification.new do |s| # s.add_runtime_dependency %q, [">= 2.0.0"] s.add_runtime_dependency %q, [">= 3.0.10"] + s.add_runtime_dependency "active_ldap" - s.add_development_dependency %q, ["~> 1.0.0"] + s.add_development_dependency %q, ["~> 1.0"] s.add_development_dependency %q, [">= 2.5.0"] - s.add_development_dependency %q, [">= 1.6.3"] - s.add_development_dependency %q, [">= 0"] - s.add_development_dependency %q, [">= 0"] - s.add_development_dependency %q, ["~> 0.6.0"] - s.add_development_dependency %q, [">= 0"] - s.add_development_dependency %q, [">= 0"] - s.add_development_dependency %q - #s.add_development_dependency %q end diff --git a/lib/ahn_ldap.rb b/lib/ahn_ldap.rb index f72282c..48d1356 100644 --- a/lib/ahn_ldap.rb +++ b/lib/ahn_ldap.rb @@ -1,10 +1,17 @@ -require 'adhearsion' -require 'active_support/dependencies/autoload' -require 'ahn_ldap/version' -require 'adhearsion/ldap' - -class AhnLdapPlugin < Adhearsion::Plugin - init :ldap do - Ldap.start if AHN_CONFIG.ldap_enabled? - end +require "adhearsion" +require "active_support/dependencies/autoload" + +begin + require 'active_ldap' +rescue LoadError + logger.fatal "LDAP support requires the \"activeldap\" gem." + # Silence the abort so we don't get an ugly backtrace + abort "" +end + +require "ahn_ldap/version" +require "ahn_ldap/plugin" + +module AhnLDAP + end diff --git a/lib/ahn_ldap/plugin.rb b/lib/ahn_ldap/plugin.rb new file mode 100644 index 0000000..c660758 --- /dev/null +++ b/lib/ahn_ldap/plugin.rb @@ -0,0 +1,36 @@ + +module AhnLDAP + + ## + # Adhearsion Plugin that defines the LDAP configuration options + # and includes a hook to start the LDAP service in Adhearsion initialization process + class Plugin < Adhearsion::Plugin + extend ActiveSupport::Autoload + + autoload :Service + + # Default configuration for LDAP connection. + # Configure an LDAP connection using ActiveLdap. See ActiveLdap::Base.establish_connect + # for further information about the appropriate settings here. + config :ahn_ldap do + host nil , :desc => "LDAP server host" + port 389 , :desc => "LDAP server port" + base "" , :desc => <<-__ + LDAP tree that must be used in the connection + __ + bind_dn "" , :desc => <<-__ + Specific domain name that identifies the user + __ + password "" , :desc => "Password credentials" + allow_anonymous false, :desc => "valid values: true | false (default)" + try_sasl false, :desc => "valid values: true | false (default)" + end + + # Include the LDAP service in plugins initialization process + init :ahn_ldap do + Service.start + end + + end + +end \ No newline at end of file diff --git a/lib/ahn_ldap/plugin/service.rb b/lib/ahn_ldap/plugin/service.rb new file mode 100644 index 0000000..abfd0c6 --- /dev/null +++ b/lib/ahn_ldap/plugin/service.rb @@ -0,0 +1,64 @@ +module AhnLDAP + class Plugin + class Service + + class << self + + ## + # Start LDAP connection + def start + raise "Must supply a host argument to the LDAP configuration" if (config.host.nil? || config.host.empty?) + raise "Must supply a valid port to the LDAP configuration" unless config.port.is_a? Integer + + require_models + establish_connection config.host, + config.port, + config.base, + config.bind_dn, + config.password, + config.allow_anonymous, + config.try_sasl + end + + # TODO: It appears that ActiveLdap does not have a connection validation + # or reconnection routine. + #def create_call_hook_for_connection_cleanup + # Events.register_callback([:asterisk, :before_call]) do + # ActiveLdap::Base.verify_active_connections! + # end + #end + + ## + # Release LDAP connection + def stop + ActiveLdap::Base.remove_connection + end + + private + + def require_models + Adhearsion.config.files_from_setting("paths", "models").each do |model| + load model + end + end + + ## + # Open LDAP connection + def establish_connection host, port, base, bind_dn, password, allow_anonymous, try_sasl + ActiveLdap::Base.setup_connection :host => host, + :port => port, + :base => base, + :logger => logger, + :bind_dn => bind_dn, + :password => password, + :allow_anonymous => allow_anonymous, + :try_sasl => try_sasl + end + + def config + @config ||= Adhearsion.config[:ahn_ldap] + end + end + end # Service + end # Plugin +end # AhnLDAP \ No newline at end of file diff --git a/lib/ahn_ldap/version.rb b/lib/ahn_ldap/version.rb index ee852b8..5676716 100644 --- a/lib/ahn_ldap/version.rb +++ b/lib/ahn_ldap/version.rb @@ -1,3 +1,3 @@ module AhnLDAP - VERSION = "0.0.1" + VERSION = "0.1.0" end diff --git a/spec/ahn_ldap/plugin/service_spec.rb b/spec/ahn_ldap/plugin/service_spec.rb new file mode 100644 index 0000000..361afe3 --- /dev/null +++ b/spec/ahn_ldap/plugin/service_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe AhnLDAP::Plugin::Service do + + describe "while initializing" do + after do + reset_ahn_ldap_config + end + + it "should raise an exception when no host has been configured" do + lambda {Adhearsion::Plugin.load}.should raise_error "Must supply a host argument to the LDAP configuration" + end + + it "should raise an exception when an invalid port has been configured" do + Adhearsion.config[:ahn_ldap].host = "localhost" + Adhearsion.config[:ahn_ldap].port = "389" + lambda {Adhearsion::Plugin.load}.should raise_error "Must supply a valid port to the LDAP configuration" + end + end + + describe "when starting the LDAP connection" do + before do + Adhearsion.config[:ahn_ldap].host = "localhost" + end + + after do + reset_ahn_ldap_config + end + + it "should call Connection.start method with the valid parameters" do + AhnLDAP::Plugin::Service.should_receive(:establish_connection).with("localhost", 389, "", "", "", false, false).and_return true + Adhearsion.config.should_receive(:files_from_setting).with("paths", "models").and_return [] + Adhearsion::Plugin.load + end + + end + +end diff --git a/spec/ahn_ldap/plugin_spec.rb b/spec/ahn_ldap/plugin_spec.rb new file mode 100644 index 0000000..0bcad7c --- /dev/null +++ b/spec/ahn_ldap/plugin_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper' + +describe AhnLDAP::Plugin do + + describe "while accessing the plugin configuration" do + + it "should retrieve a valid configuration instance" do + Adhearsion.config.ahn_ldap.should be_instance_of Loquacious::Configuration + end + + it "should configure properly the host" do + Adhearsion.config[:ahn_ldap].host.should be_nil + end + + it "should configure properly the port" do + Adhearsion.config[:ahn_ldap].port.should == 389 + end + + it "should configure properly the base" do + Adhearsion.config[:ahn_ldap].base.should be_empty + end + + it "should configure properly the bind_dn" do + Adhearsion.config[:ahn_ldap].bind_dn.should be_empty + end + + it "should configure properly the password" do + Adhearsion.config[:ahn_ldap].password.should be_empty + end + + it "should configure properly the anonymous property" do + Adhearsion.config[:ahn_ldap].allow_anonymous.should be_false + end + + it "should configure properly the try_sasl property" do + Adhearsion.config[:ahn_ldap].try_sasl.should be_false + end + + end + + describe "while configuring a specific config value" do + after do + reset_ahn_ldap_config + end + + it "ovewrites properly the host value" do + Adhearsion.config[:ahn_ldap].host = "localhost" + Adhearsion.config[:ahn_ldap].host.should == "localhost" + end + + it "ovewrites properly the port value" do + Adhearsion.config[:ahn_ldap].port = 489 + Adhearsion.config[:ahn_ldap].port.should == 489 + end + + it "ovewrites properly the base value" do + Adhearsion.config[:ahn_ldap].base = "ou = value" + Adhearsion.config[:ahn_ldap].base.should == "ou = value" + end + + it "ovewrites properly the bind_dn value" do + Adhearsion.config[:ahn_ldap].bind_dn = "uid = foo@bar" + Adhearsion.config[:ahn_ldap].bind_dn.should == "uid = foo@bar" + end + + it "ovewrites properly the password value" do + Adhearsion.config[:ahn_ldap].password = "valid-credentials" + Adhearsion.config[:ahn_ldap].password.should == "valid-credentials" + end + + it "ovewrites properly the allow_anonymous value" do + Adhearsion.config[:ahn_ldap].allow_anonymous = true + Adhearsion.config[:ahn_ldap].allow_anonymous.should be_true + end + + it "ovewrites properly the try_sasl value" do + Adhearsion.config[:ahn_ldap].try_sasl = true + Adhearsion.config[:ahn_ldap].try_sasl.should be_true + end + + end + + describe "while loading plugins" do + it "should load the init block and start the service" do + AhnLDAP::Plugin::Service.should_receive(:start).once.and_return true + Adhearsion::Plugin.load + end + end +end \ No newline at end of file diff --git a/spec/ahn_ldap_spec.rb b/spec/ahn_ldap_spec.rb index f052ac7..520b212 100644 --- a/spec/ahn_ldap_spec.rb +++ b/spec/ahn_ldap_spec.rb @@ -1,4 +1,11 @@ require 'spec_helper' describe AhnLDAP do + + subject { AhnLDAP } + + it "should be a module" do + subject.should be_kind_of Module + end + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ea13d92..673ad27 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,23 +1,11 @@ -require 'simplecov' -require 'simplecov-rcov' -class SimpleCov::Formatter::MergedFormatter - def format(result) - SimpleCov::Formatter::HTMLFormatter.new.format(result) - SimpleCov::Formatter::RcovFormatter.new.format(result) - end -end -SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter -SimpleCov.start do - add_filter "/vendor/" -end - require 'ahn_ldap' -require 'mocha' - -Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f} -RSpec.configure do |config| - config.mock_with :mocha - config.filter_run :focus => true - config.run_all_when_everything_filtered = true -end +def reset_ahn_ldap_config + Adhearsion.config[:ahn_ldap].host = nil + Adhearsion.config[:ahn_ldap].port = 389 + Adhearsion.config[:ahn_ldap].base = "" + Adhearsion.config[:ahn_ldap].bind_dn = "" + Adhearsion.config[:ahn_ldap].password = "" + Adhearsion.config[:ahn_ldap].allow_anonymous = false + Adhearsion.config[:ahn_ldap].try_sasl = false +end \ No newline at end of file