8

I am using version 0.7.7 of the Sorcery Authentication Gem by NoamB on my Rails 3.2 App

I am looking for a possibility how i can hook up a method which is doing the user info mapping for a specific external login provider (e.g. facebook, twitter).

For example I want to change the provided locale to the format I use in my database or I want to download the user avatar from twitter as part of the matching process.

By default it is only possible this way over the sorcery.rb file:

config.facebook.user_info_mapping = {:email => "email", :first_name => "first_name", :last_name => "last_name" ...

I know I can achieve such behavior with setter methods on my user model but I want to keep these things separate from the model and I want to be able to define them specifically for each provider.

Is this possible? / What is the best way to implement such extended mapping options?

Thanks for your help!

georgebrock
  • 28,393
  • 13
  • 77
  • 72
alex
  • 4,922
  • 7
  • 37
  • 51

1 Answers1

0

It looks like you could do this by extending the various Sorcery provider classes to add the application-specific fields you want to the user info hash.

For example, to use Twitter you might have something like this defined:

config.external_providers = [:twitter]

You could change this to:

config.external_providers = [:TwitterWithAvatar]

Now you need to define the TwitterWithAvatar provider under Sorcery::Providers, and override the #get_user_hash method:

module Sorcery
  module Providers
    class TwitterWithAvatar < Twitter
      def get_user_hash(access_token)
        user_hash = super
        user_hash.merge(
          avatar: get_avatar(user_hash[:uid]),
        )
      end

      private

      def get_avatar(uid)
        # Some Twitter API call
      end
    end
  end
end

Now you could set up your mapping:

config.TwitterWithAvatar.user_info_mapping = {avatar: "avatar"}

Alternatively, since you're already using a custom provider class, you could move your mapping into that class:

module Sorcery
  module Providers
    class TwitterWithAvatar < Twitter
      def user_info_mapping
        {
          avatar: "avatar",
          # ...
        }
      end
    end
  end
end

(I haven't tried running this code, so the details might be a little off, but from reading the Sorcery source code this looks like the right direction.)

georgebrock
  • 28,393
  • 13
  • 77
  • 72