brainpickin_remote_auth 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gem 'rake'
3
+ gem "jeweler", "~> 1.8.4"
4
+ gem "rspec", "~> 2.13.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,30 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.2.4)
5
+ git (1.2.5)
6
+ jeweler (1.8.4)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rdoc
11
+ json (1.7.7)
12
+ rake (10.0.4)
13
+ rdoc (4.0.1)
14
+ json (~> 1.4)
15
+ rspec (2.13.0)
16
+ rspec-core (~> 2.13.0)
17
+ rspec-expectations (~> 2.13.0)
18
+ rspec-mocks (~> 2.13.0)
19
+ rspec-core (2.13.1)
20
+ rspec-expectations (2.13.0)
21
+ diff-lcs (>= 1.1.3, < 2.0)
22
+ rspec-mocks (2.13.1)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ jeweler (~> 1.8.4)
29
+ rake
30
+ rspec (~> 2.13.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 brainpickin P.E.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,77 @@
1
+ = brainpickin_remote_auth
2
+
3
+ brainpickin_remote_auth is a simple gem providing help with brainpickin's Single Sign On
4
+ functionality (see https://my.brainpickin.com/api/remote_authentication).
5
+
6
+ == Installation and Setup
7
+
8
+ * Install:
9
+ gem install brainpickin_remote_auth
10
+
11
+ * Setup:
12
+ You will need to give the gem your token and authentication url,
13
+ perhaps in an initializer:
14
+ Brainpickin::RemoteAuth.token = 'OUR-SECRET-TOKEN'
15
+ Brainpickin::RemoteAuth.auth_url = 'https://yoursubdomain.brainpickin.com/access/remote/'
16
+
17
+
18
+ == Usage
19
+
20
+ Mixin the Brainpickin::RemoteAuthHelper module wherever needed, then call:
21
+ brainpickin_remote_auth_url(:name => 'user name',
22
+ :email => 'user email',
23
+ <optional params>)
24
+
25
+ This will return a url you can redirect the user to to log them in to
26
+ your brainpickin account.
27
+
28
+ As a convenience, you can pass a user object to brainpickin_remote_auth_url:
29
+ brainpickin_remote_auth_url(user)
30
+
31
+ This user must respond_to? :name and :email, and its :id will be used
32
+ as the :external_id (making it useless with user objects that return
33
+ an ephemeral object_id, but works well with ActiveRecord and the
34
+ like).
35
+
36
+ This method will generate and include the hash of the parameters for
37
+ you if necessary.
38
+
39
+ == Example Auth Controller
40
+
41
+ Here is an example controller that handles login and logout for
42
+ brainpickin:
43
+
44
+ # Uses restful-authentication style auth.
45
+ #
46
+ # Define the following in routes.rb:
47
+
48
+ # match 'services/brainpickin_auth' => 'services#brainpickin_auth'
49
+ # match 'services/brainpickin_logout' => 'services#brainpickin_logout'
50
+
51
+ class brainpickinAuthController < ApplicationController
52
+ include Brainpickin::RemoteAuthHelper
53
+
54
+ skip_before_filter :login_required, :only => :logout
55
+
56
+ def brainpickin_auth
57
+ redirect_to brainpickin_remote_auth_url(current_user)
58
+ end
59
+
60
+ def brainpickin_logout
61
+ redirect_to logout_url
62
+ end
63
+
64
+ protected
65
+ def login_required
66
+ if !logged_in?
67
+ flash[:notice] = 'You must log in to access to brainpickin site.'
68
+ store_location
69
+ redirect_to login_path
70
+ end
71
+ end
72
+ end
73
+
74
+
75
+ == Copyright
76
+
77
+ Copyright (c) 2013 brainpickin. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "brainpickin_remote_auth"
8
+ gem.summary = %Q{Helper for brainpickin Single Sign In/remote authentication}
9
+ gem.description = %Q{See the README.}
10
+ gem.email = "eli@brainpickin.com"
11
+ gem.homepage = "http://github.com/purian/brainpickin_remote_auth"
12
+ gem.authors = ["Eli Purian"]
13
+ gem.add_dependency "activesupport", ">= 3.0.0"
14
+ gem.add_development_dependency "rspec", ">= 2.6.0"
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rspec/core'
22
+ require 'rspec/core/rake_task'
23
+ RSpec::Core::RakeTask.new(:spec) do |spec|
24
+ spec.pattern = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
28
+ spec.pattern = 'spec/**/*_spec.rb'
29
+ spec.rcov = true
30
+ end
31
+
32
+ task :default => :spec
33
+
34
+ begin
35
+ require 'yard'
36
+ YARD::Rake::YardocTask.new
37
+ rescue LoadError
38
+ task :yardoc do
39
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
40
+ end
41
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,61 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "brainpickin_remote_auth"
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Eli Purian"]
12
+ s.date = "2013-04-28"
13
+ s.description = "See the README."
14
+ s.email = "eli@brainpickin.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "brainpickin_remote_auth.gemspec",
28
+ "lib/brainpickin_remote_auth.rb",
29
+ "spec/brainpickin_remote_auth_spec.rb",
30
+ "spec/spec_helper.rb"
31
+ ]
32
+ s.homepage = "http://github.com/purian/brainpickin_remote_auth"
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = "1.8.25"
35
+ s.summary = "Helper for brainpickin Single Sign In/remote authentication"
36
+
37
+ if s.respond_to? :specification_version then
38
+ s.specification_version = 3
39
+
40
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
41
+ s.add_runtime_dependency(%q<rake>, [">= 0"])
42
+ s.add_runtime_dependency(%q<jeweler>, ["~> 1.8.4"])
43
+ s.add_runtime_dependency(%q<rspec>, ["~> 2.13.0"])
44
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0"])
45
+ s.add_development_dependency(%q<rspec>, [">= 2.6.0"])
46
+ else
47
+ s.add_dependency(%q<rake>, [">= 0"])
48
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
49
+ s.add_dependency(%q<rspec>, ["~> 2.13.0"])
50
+ s.add_dependency(%q<activesupport>, [">= 3.0.0"])
51
+ s.add_dependency(%q<rspec>, [">= 2.6.0"])
52
+ end
53
+ else
54
+ s.add_dependency(%q<rake>, [">= 0"])
55
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
56
+ s.add_dependency(%q<rspec>, ["~> 2.13.0"])
57
+ s.add_dependency(%q<activesupport>, [">= 3.0.0"])
58
+ s.add_dependency(%q<rspec>, [">= 2.6.0"])
59
+ end
60
+ end
61
+
@@ -0,0 +1,81 @@
1
+ require 'digest/md5'
2
+ require 'active_support/core_ext/object' #gives us Hash.to_query
3
+
4
+ ##
5
+ # Provides a helper to use brainpickin's SSO/remote auth service.
6
+ # see: https://my.brainpickin.com/api/remote_authentication
7
+ module Brainpickin
8
+
9
+ ##
10
+ # Handles storing the token and auth_url (endpoint) for the brainpickin side.
11
+ class RemoteAuth
12
+ class << self
13
+ attr_writer :auth_url, :token
14
+
15
+ def token
16
+ raise ArgumentError.new('brainpickin token must be set. Set with Brainpickin::RemoteAuth.token = <token>') unless @token
17
+ @token
18
+ end
19
+
20
+ def auth_url
21
+ raise ArgumentError.new('brainpickin auth_url must be set. Set with Brainpickin::RemoteAuth.auth_url = <url>') unless @auth_url
22
+ @auth_url
23
+ end
24
+ end
25
+ end
26
+
27
+ ##
28
+ # Provides the method that generates the auth url. Mixin where required.
29
+ module RemoteAuthHelper
30
+ ##
31
+ # Takes a hash of parameters and generates the hashed auth
32
+ # url. The hash must include the :name and :email for the user.
33
+ # See: https://my.brainpickin.com/api/remote_authentication for a list
34
+ # of all of the parameters.
35
+ #
36
+ # If the :timestamp is not provided, Time.now will be used. If an
37
+ # :external_id is provided, then the :hash will be generated.
38
+ #
39
+ # As a convenience, a user object can be passed instead, but must
40
+ # respond_to? at least :email and :name. The :id of the user
41
+ # object will be used as the :external_id.
42
+
43
+ def brainpickin_remote_auth_url(user_or_params)
44
+ params = user_or_params.is_a?(Hash) ? user_or_params : user_to_params(user_or_params)
45
+ validate_params(params)
46
+ params[:timestamp] = Time.now.utc.to_i unless params[:timestamp]
47
+ params[:hash] = params[:external_id] ? generate_hash(Brainpickin::RemoteAuth.token, params) : ''
48
+
49
+ "#{Brainpickin::RemoteAuth.auth_url}?#{params.to_query}"
50
+ end
51
+
52
+ private
53
+ def user_to_params(user)
54
+ params = { }
55
+ [[:email, :email],
56
+ [:name, :name],
57
+ [:external_id, :id]].each do |param, field|
58
+ params[param] = user.send(field) if user.respond_to?(field)
59
+ end
60
+ params
61
+ end
62
+
63
+ def validate_params(params)
64
+ [:email, :name].each do |param|
65
+ raise ArgumentError.new("Required parameter :#{param} not given") unless params[param]
66
+ end
67
+ end
68
+
69
+ def generate_hash(token, params)
70
+ str_to_hash = params[:name].clone
71
+ str_to_hash << params[:email]
72
+ str_to_hash << params[:external_id].to_s if params[:external_id]
73
+ str_to_hash << params[:interests].to_s if params[:interests]
74
+ str_to_hash << params[:remote_photo_url].to_s if params[:remote_photo_url]
75
+ str_to_hash << token
76
+ str_to_hash << params[:timestamp].to_s
77
+ Digest::MD5.hexdigest(str_to_hash)
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ describe Brainpickin::RemoteAuth do
4
+
5
+ before(:each) do
6
+ @auth = Object.new
7
+ @auth.extend(Brainpickin::RemoteAuthHelper)
8
+ end
9
+
10
+ context 'RemoteAuth' do
11
+ before(:each) do
12
+ Brainpickin::RemoteAuth.token = Brainpickin::RemoteAuth.auth_url = nil
13
+ end
14
+
15
+ it 'should raise exception if token is not set' do
16
+ lambda{ Brainpickin::RemoteAuth.token }.should raise_error(ArgumentError)
17
+ end
18
+
19
+ it 'should return the token without exception if it is set' do
20
+ Brainpickin::RemoteAuth.token = 'blah'
21
+ Brainpickin::RemoteAuth.token.should == 'blah'
22
+ end
23
+
24
+
25
+ it 'should raise exception if auth_url is not set' do
26
+ lambda { Brainpickin::RemoteAuth.auth_url }.should raise_error(ArgumentError)
27
+ end
28
+
29
+ it 'should return the auth_url without exception if it is set' do
30
+ Brainpickin::RemoteAuth.auth_url = 'blah'
31
+ Brainpickin::RemoteAuth.auth_url.should == 'blah'
32
+ end
33
+ end
34
+
35
+
36
+ context 'url generation' do
37
+ before(:each) do
38
+ Brainpickin::RemoteAuth.token = 'the_token'
39
+ Brainpickin::RemoteAuth.auth_url = 'the_url'
40
+ @valid_params = { :email => 'test@example.com', :name => 'blah'}
41
+ end
42
+
43
+ context 'required fields' do
44
+ it 'should raise an argument error the name is not provided' do
45
+ lambda {
46
+ @valid_params.delete(:name)
47
+ @auth.brainpickin_remote_auth_url(@valid_params)
48
+ }.should raise_error(ArgumentError)
49
+ end
50
+
51
+ it 'should raise an argument error the email is not provided' do
52
+ lambda {
53
+ @valid_params.delete(:email)
54
+ @auth.brainpickin_remote_auth_url(@valid_params)
55
+ }.should raise_error(ArgumentError)
56
+ end
57
+
58
+ end
59
+
60
+ it 'should return a url that starts with the auth_url' do
61
+ @auth.brainpickin_remote_auth_url(@valid_params)
62
+ end
63
+
64
+ it 'should have an empty hash param if external_id not provided' do
65
+ @auth.brainpickin_remote_auth_url(@valid_params).should =~ /hash=(&|$)/
66
+ end
67
+
68
+ it 'should have a hash param if external_id provided' do
69
+ @auth.brainpickin_remote_auth_url(@valid_params.merge(:external_id => 'id')).should_not =~ /hash=(&|$)/
70
+ end
71
+
72
+ it 'should have a different hash param if external_id and remote_photo_url provided ' do
73
+ a=@auth.brainpickin_remote_auth_url(@valid_params.merge(:external_id => 'id')).match(/(hash=[^&]*)/)[1]
74
+ b=@auth.brainpickin_remote_auth_url(@valid_params.merge(:external_id => 'id', :remote_photo_url => 'photo_url')).match(/(hash=[^&]*)/)[1]
75
+ a.should_not == b
76
+ end
77
+
78
+ context 'given a user object' do
79
+ before(:each) do
80
+ @user = mock
81
+ @user.should_receive(:name).and_return('a_name')
82
+ @user.should_receive(:email).and_return('an_email')
83
+ end
84
+
85
+ it 'should pull the name from the user' do
86
+ @auth.brainpickin_remote_auth_url(@user).should =~ /name=a_name/
87
+ end
88
+
89
+ it 'should pull the email from the user' do
90
+ @auth.brainpickin_remote_auth_url(@user).should =~ /email=an_email/
91
+ end
92
+
93
+ it 'should pull the id from the user' do
94
+ @user.should_receive(:id).and_return('an_id')
95
+ @auth.brainpickin_remote_auth_url(@user).should =~ /external_id=an_id/
96
+ end
97
+
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'brainpickin_remote_auth'
4
+
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: brainpickin_remote_auth
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eli Purian
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
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: jeweler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.8.4
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: 1.8.4
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.13.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.13.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: activesupport
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 3.0.0
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 3.0.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 2.6.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 2.6.0
94
+ description: See the README.
95
+ email: eli@brainpickin.com
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files:
99
+ - LICENSE
100
+ - README.rdoc
101
+ files:
102
+ - .document
103
+ - Gemfile
104
+ - Gemfile.lock
105
+ - LICENSE
106
+ - README.rdoc
107
+ - Rakefile
108
+ - VERSION
109
+ - brainpickin_remote_auth.gemspec
110
+ - lib/brainpickin_remote_auth.rb
111
+ - spec/brainpickin_remote_auth_spec.rb
112
+ - spec/spec_helper.rb
113
+ homepage: http://github.com/purian/brainpickin_remote_auth
114
+ licenses: []
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ segments:
126
+ - 0
127
+ hash: -3391257356349651697
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 1.8.25
137
+ signing_key:
138
+ specification_version: 3
139
+ summary: Helper for brainpickin Single Sign In/remote authentication
140
+ test_files: []