Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a custom Devise Strategy

Been fighting with this for a while now, not sure why it isn't working.

The gist is looking to use Devise with LDAP. I don't need to do anything except for authenticate so I have no need to use anything except for a custom strategy.

I created one based on https://github.com/plataformatec/devise/wiki/How-To:-Authenticate-via-LDAP and as far as I can tell everything should work except whenever I try to run the server (or rake route) I get a NameError

lib/devise/models.rb:88:in `const_get': uninitialized constant Devise::Models::LdapAuthenticatable (NameError)

I've traced the error down to my app/models/user.rb

class User < ActiveRecord::Base
  devise :ldap_authenticatable, :rememberable, :trackable, :timeoutable
end

If I remove :ldap_authenticatable then the crash goes away but I have no routes to user#session and a login prompt cannot be accessed.

My supporting files:

lib/ldap_authenticatable.rb

require 'net/ldap'
require 'devise/strategies/authenticatable'

module Devise
  module Strategies
    class LdapAuthenticatable < Authenticatable

      def authenticate!
        if params[:user]
          ldap = Net::LDAP.new
          ldap.host = 'redacted'
          ldap.port = 389
          ldap.auth login, password

          if ldap.bind
            user = User.where(login: login).first_or_create do |user|
            success!(user)
          else
            fail(:invalid_login)
          end
        end
      end

      def login
        params[:user][:login]
      end

      def password
        params[:user][:password]
      end

    end
  end
end

Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)

And finally, inside config/initializers/devise.rb

Devise.setup do |config|
  # ==> LDAP Configuration
  require 'ldap_authenticatable'
  config.warden do |manager|
    manager.default_strategies(:scope => :user).unshift :ldap_authenticatable
  end
end

I've exhausted my searches, maybe someone can see something I am missing.

Cheers

like image 204
Mike Gabriel Avatar asked Aug 19 '14 00:08

Mike Gabriel


2 Answers

Is your lib/ldap_authenticatable.rb is in the autoload path or explicitly required? Since Rails 3 code in lib folder isn't autoloaded by default any more. Here is one way on how to solve it

IMHO Devise is a great gem. However in order to write your own strategy you have to be familiar not only with Devise but with Warden source code as well, and a lot of boilerplate code needs to be written in various places, so I start to investigate how to make customizations easier for Devise and come up with this gem devise_custom_authenticatable. You can check it and probably it'll solve your problem in a different way. This gem is used in production code base for rather busy application, so it battle proven :)

like image 91
AMe Avatar answered Sep 18 '22 18:09

AMe


File paths should match namespaces. You need to add 2 levels of directories.

mkdir lib/devise  
mkdir lib/devise/strategies  
mv lib/ldap_authenticatable.rb lib/devise/strategies/ldap_authenticatable.rb  

Since you are namespaced to

module Devise  
  module Strategies  
    class LdapAuthenticatable < Authenticatable  
...  
like image 27
csi Avatar answered Sep 17 '22 18:09

csi