copies_omniauth 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+ gemspec
3
+ gem 'rails'
4
+ group :test do
5
+ gem 'rspec'
6
+ gem 'rspec-rails'
7
+ gem 'sqlite3'
8
+ end
data/README.markdown ADDED
@@ -0,0 +1,81 @@
1
+ ![OmniAuth Image](http://blog.deanbrundage.com/wp-content/uploads/2012/01/copies_omniauth.png)
2
+
3
+ A small gem for copying [OmniAuth](https://github.com/intridea/omniauth "OmniAuth") information into models
4
+
5
+ # Usage #
6
+
7
+ class FacebookProfile
8
+ include CopiesOmniauth
9
+
10
+ attr_accessor :email
11
+ attr_accessor :first_name
12
+ attr_accessor :last_name
13
+ attr_accessor :token
14
+ attr_accessor :uid
15
+
16
+ copies_omniauth :attributes => { :email => %w(info email),
17
+ :first_name => %w(info first_name),
18
+ :last_name => %w(info last_name)
19
+ }
20
+ end
21
+
22
+ f = FacebookProfile.new_from_omniauth(omniauth)
23
+
24
+ ## Arguments ##
25
+
26
+ The `copies_omniauth` method takes a hash with two keys `:options` and `:attributes`
27
+
28
+ ### Options ###
29
+
30
+ * `:overwrite` Always overwrite information (default: *true*)
31
+ * `:secret_attribute` The attribute on the class used to store OmniAuth's secret (default: *:secret*)
32
+ * `:skip_provider_check` Do not verify the OmniAuth provider matches the model (default: *false*)
33
+ * `:token_attribute` The attribute on the class used to store OmniAuth's token (default: *:token*)
34
+ * `:uid_attribute` The attribute on an instance used to store OmniAuth's uid (default: *:uid*)
35
+ * `:provider_name` CopiesOmniauth will guess the expected OmniAuth provider from the class name by chopping "Provider" off the end of the name. To override this behavior, set the `:provider_name` option.
36
+
37
+ ### Attributes ###
38
+
39
+ **Copies OmniAuth always copies `secret`, `token`, and `uid` if setters are present on the model.**
40
+
41
+ The `:attributes` parameter tells CopiesOmniauth which attributes to set on an instance and how to find their values in the OmniAuth hash. Keys of the parameter represent instance attributes and their values represent a path in the OmniAuth hash. Given the following OmniAuth hash:
42
+
43
+ { "provider" => "twitter",
44
+ "uid" => "10223402",
45
+ "info" => { "name" => "Dean Brundage",
46
+ "email" => "dean@deanbrundage.com",
47
+ "nickname" => "brundage",
48
+ "urls" => [ "blog" => "http://blog.deanbrundage.com" ]
49
+ ....
50
+ }
51
+ "credentials" => { "token" => "....",
52
+ "secret" => "....",
53
+ ....
54
+ }
55
+ }
56
+
57
+ And given a model:
58
+
59
+ class TwitterProfile
60
+ attr_accessor :real_name
61
+ end
62
+
63
+ To copy the "name" attribute into your model's "real_name" attribute:
64
+
65
+ copies_omniauth :attributes => { :real_name => ["info", "name"] }
66
+
67
+ This traverses the OmniAuth hash, sending _info_, then _name_ and stores the value in the model's `real_name` attribute
68
+
69
+ # Methods #
70
+
71
+ ## Class Methods ##
72
+
73
+ `copies_omniauth` Configuration macro
74
+
75
+ `new_from_omniauth(omniauth_hash)` Calls `new`, then `copy_from_omniauth(omniauth_hash)`
76
+
77
+ `create_from_omniauth(omniauth_hash)` Calls `new_from_omniauth(omniauth_hash)` then `save` -- useful for `ActiveRecord` models
78
+
79
+ ## Instance Methods ##
80
+
81
+ `copy_from_omniauth(omniauth_hash)` Copies values from `omniauth_hash` into the instance
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rspec/core/rake_task'
4
+
5
+ task :default => :spec
6
+
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.pattern = "./spec/specs/*_spec.rb"
9
+ end
10
+
@@ -0,0 +1,157 @@
1
+ require 'copies_omniauth/version'
2
+
3
+ module CopiesOmniauth
4
+
5
+ SECRET_KEY = ["credentials","secret"]
6
+ TOKEN_KEY = ["credentials","token"]
7
+ UID_KEY = "uid"
8
+
9
+ class ProviderNameMismatch < RuntimeError; end
10
+ class UidMismatch < RuntimeError; end
11
+
12
+
13
+ if defined?(Rails)
14
+ require 'copies_omniauth/railtie'
15
+ end
16
+
17
+
18
+ def self.included(parent)
19
+ parent.extend ClassMethods
20
+ end
21
+
22
+
23
+ module ClassMethods
24
+
25
+ def copies_omniauth(args={})
26
+ options = self.class_variable_set( :@@copies_omniauth_options,
27
+ { :overwrite => true,
28
+ :provider_name => self.name.sub("Profile","").downcase,
29
+ :secret_attribute => :secret,
30
+ :skip_provider_check => false,
31
+ :token_attribute => :token,
32
+ :uid_attribute => :uid
33
+ })
34
+ unless args[:options].nil?
35
+ options.merge!(args[:options])
36
+ end
37
+
38
+ attributes = self.class_variable_set( :@@copies_omniauth_attributes,
39
+ { options[:secret_attribute] => SECRET_KEY,
40
+ options[:token_attribute] => TOKEN_KEY,
41
+ options[:uid_attribute] => UID_KEY
42
+ })
43
+ unless args[:attributes].nil?
44
+ attributes.merge!(args[:attributes])
45
+ end
46
+
47
+ [ options[:secret_attribute],
48
+ options[:token_attribute],
49
+ options[:uid_attribute] ].each do |attr|
50
+ attributes.delete(attr) unless instance_has_setter_for?(attr)
51
+ end
52
+
53
+ attributes.each do |attr,omniauth_key|
54
+ case omniauth_key
55
+ when Array, String, Symbol
56
+ else
57
+ raise ArgumentError, "Don't know how to traverse OmniAuth with #{omniauth_key}"
58
+ end
59
+ end
60
+ include CopiesOmniauth::InstanceMethods
61
+ end
62
+
63
+
64
+ def create_from_omniauth(omniauth)
65
+ new_from_omniauth(omniauth).save
66
+ end
67
+
68
+
69
+ def new_from_omniauth(omniauth)
70
+ new().copy_from_omniauth(omniauth)
71
+ end
72
+
73
+
74
+ private
75
+
76
+ def attribute_setter_for?(attr)
77
+ respond_to?(:attribute_method?) && attribute_method?(attr)
78
+ end
79
+
80
+
81
+ def instance_has_setter_for?(attr)
82
+ attribute_setter_for?(attr) || method_setter_for?(attr)
83
+ end
84
+
85
+
86
+ def method_setter_for?(attr)
87
+ instance_methods.include?("#{attr}=".to_sym)
88
+ end
89
+
90
+ end
91
+
92
+
93
+ module InstanceMethods
94
+
95
+ def copy_from_omniauth(omniauth)
96
+
97
+ validate_provider omniauth["provider"]
98
+ validate_uid omniauth["uid"]
99
+
100
+ copies_omniauth_attributes.each do |attr,omniauth_key|
101
+
102
+ case omniauth_key
103
+ when Array
104
+ value = omniauth_key.inject(omniauth) do |hash,key|
105
+ hash[key] unless hash.nil?
106
+ end
107
+ when String
108
+ value = omniauth[omniauth_key]
109
+
110
+ when Symbol
111
+ value = omniauth[omniauth_key.to_s]
112
+
113
+ end
114
+
115
+ if copies_omniauth_options[:overwrite] || send(attr).nil?
116
+ self.send("#{attr}=",value)
117
+ end
118
+ end
119
+ self
120
+ end
121
+
122
+ private
123
+
124
+ def copies_omniauth_attributes
125
+ self.class.class_variable_get(:@@copies_omniauth_attributes)
126
+ end
127
+
128
+
129
+ def copies_omniauth_options
130
+ self.class.class_variable_get(:@@copies_omniauth_options)
131
+ end
132
+
133
+
134
+ def omniauth_uid
135
+ if respond_to?(copies_omniauth_options[:uid_attribute])
136
+ send(copies_omniauth_options[:uid_attribute])
137
+ end
138
+ end
139
+
140
+
141
+ def validate_provider(provider)
142
+ return if copies_omniauth_options[:skip_provider_check]
143
+ unless provider == copies_omniauth_options[:provider_name].to_s
144
+ raise ProviderNameMismatch, "OmniAuth (#{provider}) does not represent a #{copies_omniauth_options[:provider_name]} profile."
145
+ end
146
+ end
147
+
148
+
149
+ def validate_uid(uid)
150
+ if ! omniauth_uid.nil? && uid != omniauth_uid
151
+ raise UidMismatch, "OmniAuth (#{uid}) does not apply to this #{copies_omniauth_options[:provider_name]} profile (#{omniauth_uid})."
152
+ end
153
+ end
154
+
155
+ end
156
+
157
+ end
@@ -0,0 +1,13 @@
1
+ require 'copies_omniauth'
2
+ require 'rails'
3
+ module CopiesOmniauth
4
+ class Railtie < Rails::Railtie
5
+
6
+ initializer "active_record.copies_omniauth" do |app|
7
+ ActiveSupport.on_load :active_record do
8
+ include CopiesOmniauth
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module CopiesOmniauth
2
+ VERSION = '0.0.9'
3
+ end
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: ":memory:"
data/spec/db/schema.rb ADDED
@@ -0,0 +1,9 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+
3
+ create_table :active_record_profiles, :force => true do |t|
4
+ t.string :name, :null => false
5
+ t.string :uid, :null => false
6
+ t.string :token, :null => false
7
+ end
8
+
9
+ end
@@ -0,0 +1,3 @@
1
+ class ActiveRecordProfile < ActiveRecord::Base
2
+ # copies_omniauth
3
+ end
@@ -0,0 +1,7 @@
1
+ class DummyProfile
2
+ include CopiesOmniauth
3
+ attr_accessor :name
4
+ attr_accessor :token
5
+ attr_accessor :uid
6
+ copies_omniauth :attributes => { :name => %w(info name) }
7
+ end
@@ -0,0 +1,4 @@
1
+ class NodefaultsProfile
2
+ include CopiesOmniauth
3
+ copies_omniauth
4
+ end
@@ -0,0 +1,12 @@
1
+ class NonstandardInfo
2
+ include CopiesOmniauth
3
+ attr_accessor :ident
4
+ attr_accessor :provider_uid
5
+ attr_accessor :name
6
+
7
+ copies_omniauth( :attributes => { :name => %w(info name) },
8
+ :options => { :provider_name => :irregular,
9
+ :token_attribute => :ident,
10
+ :uid_attribute => :provider_uid
11
+ })
12
+ end
@@ -0,0 +1,27 @@
1
+ :dummy:
2
+ provider: "dummy"
3
+ uid: 1
4
+ info:
5
+ name: "A Dummy Profile"
6
+ credentials:
7
+ token: "blue"
8
+
9
+ :error:
10
+ provider: "error"
11
+ uid: 1
12
+ credentials:
13
+ token: "blue"
14
+
15
+ :irregular:
16
+ provider: "irregular"
17
+ uid: 1
18
+ info:
19
+ name: "An Irregular Profile"
20
+ credentials:
21
+ token: "blue"
22
+
23
+ :nodefaults:
24
+ provider: "nodefaults"
25
+ uid: 1
26
+ credentials:
27
+ token: "blue"
@@ -0,0 +1,19 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ rspec_dir = File.dirname(__FILE__)
3
+
4
+ ENV["RAILS_ENV"] ||= "test"
5
+
6
+ require 'rails/all'
7
+ require 'copies_omniauth'
8
+
9
+ ActiveRecord::Base.configurations = YAML::load(File.open(File.join(rspec_dir, "/db", "database.yml")))
10
+ ActiveRecord::Base.establish_connection(ENV["DB"] || "test")
11
+ ActiveRecord::Base.logger = Logger.new(File.join(rspec_dir, "debug.log"))
12
+ ActiveRecord::Migration.verbose = false
13
+ load(File.join(rspec_dir, "db", "schema.rb"))
14
+
15
+ #ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
16
+
17
+ OMNIAUTHS = YAML::load(File.open(File.join(rspec_dir, "omniauths.yml")))
18
+
19
+ Dir[File.join(rspec_dir,"models","*.rb")].each { |f| require f }
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe CopiesOmniauth, 'custom behavior' do
4
+
5
+ it "copies the uid by default" do
6
+ profile = NonstandardInfo.new
7
+ profile.provider_uid.should be_nil
8
+ profile.copy_from_omniauth OMNIAUTHS[:irregular]
9
+ profile.provider_uid.should_not be_nil
10
+ profile.provider_uid.should eq OMNIAUTHS[:irregular]["uid"]
11
+ end
12
+
13
+
14
+ it "copies the token by default" do
15
+ profile = NonstandardInfo.new
16
+ profile.ident.should be_nil
17
+ profile.copy_from_omniauth OMNIAUTHS[:irregular]
18
+ profile.ident.should_not be_nil
19
+ profile.ident.should eq OMNIAUTHS[:irregular]["credentials"]["token"]
20
+ end
21
+
22
+
23
+ it "copies omniauth values requested" do
24
+ profile = NonstandardInfo.new
25
+ profile.name.should be_nil
26
+ profile.copy_from_omniauth OMNIAUTHS[:irregular]
27
+ profile.name.should_not be_nil
28
+ profile.name.should eq OMNIAUTHS[:irregular]["info"]["name"]
29
+ end
30
+
31
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe CopiesOmniauth, 'default behavior' do
4
+
5
+ it "returns self" do
6
+ profile = DummyProfile.new
7
+ profile.copy_from_omniauth(OMNIAUTHS[:dummy]).should === profile
8
+ end
9
+
10
+
11
+ it "copies the uid by default" do
12
+ profile = DummyProfile.new
13
+ profile.uid.should be_nil
14
+ profile.copy_from_omniauth OMNIAUTHS[:dummy]
15
+ profile.uid.should_not be_nil
16
+ profile.uid.should eq OMNIAUTHS[:dummy]["uid"]
17
+ end
18
+
19
+
20
+ it "does not try to copy the uid if the class doesn't have one" do
21
+ profile = NodefaultsProfile.new
22
+ profile.should_not respond_to(:uid)
23
+ expect {
24
+ profile.copy_from_omniauth OMNIAUTHS[:nodefaults]
25
+ }.not_to raise_error
26
+ end
27
+
28
+
29
+ it "copies the token by default" do
30
+ profile = DummyProfile.new
31
+ profile.token.should be_nil
32
+ profile.copy_from_omniauth OMNIAUTHS[:dummy]
33
+ profile.token.should_not be_nil
34
+ profile.token.should eq OMNIAUTHS[:dummy]["credentials"]["token"]
35
+ end
36
+
37
+
38
+ it "does not try to copy the token if the class doesn't have one" do
39
+ profile = NodefaultsProfile.new
40
+ profile.should_not respond_to(:token)
41
+ expect {
42
+ profile.copy_from_omniauth OMNIAUTHS[:nodefaults]
43
+ }.not_to raise_error
44
+ end
45
+
46
+
47
+ it "copies omniauth values requested" do
48
+ profile = DummyProfile.new
49
+ profile.name.should be_nil
50
+ profile.copy_from_omniauth OMNIAUTHS[:dummy]
51
+ profile.name.should_not be_nil
52
+ profile.name.should eq OMNIAUTHS[:dummy]["info"]["name"]
53
+ end
54
+
55
+
56
+ it "doesn't overwrite values when configured not to" do
57
+ name = "Blark"
58
+ name.should_not eq OMNIAUTHS[:dummy]["info"]["name"]
59
+ class DummyProfile
60
+ copies_omniauth(:attributes => {:name => %w(info name)},
61
+ :options => {:overwrite => false})
62
+ end
63
+ profile = DummyProfile.new
64
+ profile.name = name
65
+ profile.copy_from_omniauth OMNIAUTHS[:dummy]
66
+ profile.name.should eq name
67
+ end
68
+
69
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe CopiesOmniauth, 'exceptions' do
4
+
5
+ it "raises an error when the omniauth information does not represent the class" do
6
+ profile = DummyProfile.new
7
+ expect {
8
+ profile.copy_from_omniauth(OMNIAUTHS[:irregular])
9
+ }.to raise_error(CopiesOmniauth::ProviderNameMismatch)
10
+ end
11
+
12
+
13
+ it "raises an error if the omniauth uid does not match the model's uid" do
14
+ profile = DummyProfile.new
15
+ profile.uid = 2
16
+ profile.uid.should_not eq OMNIAUTHS[:dummy]["uid"]
17
+ expect {
18
+ profile.copy_from_omniauth(OMNIAUTHS[:dummy])
19
+ }.to raise_error(CopiesOmniauth::UidMismatch)
20
+ end
21
+
22
+
23
+ it "raises an error when the class doesn't have a setter for an attribute" do
24
+ class ErrorProfile
25
+ include CopiesOmniauth
26
+ copies_omniauth :attributes => { :no_setter_for_this => :p }
27
+ end
28
+ expect {
29
+ ErrorProfile.new.copy_from_omniauth(OMNIAUTHS[:error])
30
+ }.to raise_error(NoMethodError)
31
+ end
32
+
33
+
34
+ it "raises an error when given bad attribute traversal" do
35
+ expect {
36
+ class ErrorProfile
37
+ include CopiesOmniauth
38
+ copies_omniauth :attributes => { :bad_girl => {} }
39
+ end
40
+ }.to raise_error(ArgumentError)
41
+ end
42
+
43
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe CopiesOmniauth, 'methods' do
4
+
5
+ it "adds methods to a plain class" do
6
+ DummyProfile.should respond_to(:copies_omniauth)
7
+ end
8
+
9
+
10
+ it "adds instance methods to a plain class" do
11
+ DummyProfile.new.should respond_to(:copy_from_omniauth)
12
+ end
13
+
14
+
15
+ it "adds methods to ActiveRecord" do
16
+ ActiveRecord::Base.should respond_to(:copies_omniauth)
17
+ end
18
+
19
+
20
+ it "adds instance methods to ActiveRecord" do
21
+ ActiveRecordProfile.new.should respond_to(:copy_from_omniauth)
22
+ end
23
+
24
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe CopiesOmniauth, 'VERSION' do
4
+ it 'is present' do
5
+ CopiesOmniauth::VERSION.should_not be_nil
6
+ end
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: copies_omniauth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.9
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dean Brundage
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rails
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 3.0.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 3.0.0
46
+ description:
47
+ email: dean@deanbrundage.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - lib/copies_omniauth.rb
53
+ - lib/copies_omniauth/railtie.rb
54
+ - lib/copies_omniauth/version.rb
55
+ - Gemfile
56
+ - Rakefile
57
+ - README.markdown
58
+ - spec/db/database.yml
59
+ - spec/db/schema.rb
60
+ - spec/models/active_record_profile.rb
61
+ - spec/models/dummy_profile.rb
62
+ - spec/models/nodefaults_profile.rb
63
+ - spec/models/nonstandard_info.rb
64
+ - spec/omniauths.yml
65
+ - spec/spec_helper.rb
66
+ - spec/specs/custom_behavior_spec.rb
67
+ - spec/specs/default_behavior_spec.rb
68
+ - spec/specs/errors_spec.rb
69
+ - spec/specs/methods_spec.rb
70
+ - spec/specs/version_spec.rb
71
+ homepage: https://github.com/brundage/copies_omniauth
72
+ licenses: []
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 1.8.24
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: Utility for copying information from OmniAuth into other models
95
+ test_files:
96
+ - spec/db/database.yml
97
+ - spec/db/schema.rb
98
+ - spec/models/active_record_profile.rb
99
+ - spec/models/dummy_profile.rb
100
+ - spec/models/nodefaults_profile.rb
101
+ - spec/models/nonstandard_info.rb
102
+ - spec/omniauths.yml
103
+ - spec/spec_helper.rb
104
+ - spec/specs/custom_behavior_spec.rb
105
+ - spec/specs/default_behavior_spec.rb
106
+ - spec/specs/errors_spec.rb
107
+ - spec/specs/methods_spec.rb
108
+ - spec/specs/version_spec.rb
109
+ has_rdoc: