soundcloud-auth 0.1.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/README.markdown +2 -0
- data/Rakefile +18 -0
- data/VERSION +1 -0
- data/app/controllers/sessions_controller.rb +61 -0
- data/app/models/soundcloud_auth/generic_user.rb +119 -0
- data/config/routes.rb +6 -0
- data/generators/soundcloud_auth/USAGE +10 -0
- data/generators/soundcloud_auth/soundcloud_auth_generator.rb +13 -0
- data/generators/soundcloud_auth/templates/migration.rb +41 -0
- data/generators/soundcloud_auth/templates/soundcloud_auth.yml +17 -0
- data/generators/soundcloud_auth/templates/user.rb +5 -0
- data/init.rb +1 -0
- data/lib/soundcloud_auth.rb +51 -0
- data/lib/soundcloud_auth/controller_extensions.rb +72 -0
- data/rails/init.rb +7 -0
- metadata +96 -0
data/README.markdown
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gemspec|
|
7
|
+
gemspec.name = "soundcloud-auth"
|
8
|
+
gemspec.summary = "SoundcloudAuth is a Rails plugin gem that provides Single Sign-On capabilities for Rails applications via SoundCloud."
|
9
|
+
gemspec.description = "SoundcloudAuth is a Rails plugin gem that provides Single Sign-On capabilities for Rails applications via SoundCloud."
|
10
|
+
gemspec.email = "lee@soundcloud.com"
|
11
|
+
gemspec.homepage = "http://github.com/leemartin/soundcloud-auth"
|
12
|
+
gemspec.authors = ["Lee Martin"]
|
13
|
+
gemspec.add_dependency('oauth', '>= 0.3.1')
|
14
|
+
end
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
18
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class SessionsController < ApplicationController
|
2
|
+
|
3
|
+
unloadable
|
4
|
+
|
5
|
+
def new
|
6
|
+
|
7
|
+
oauth_callback = request.protocol + request.host_with_port + '/oauth_callback'
|
8
|
+
@request_token = SoundcloudAuth.consumer.get_request_token({:oauth_callback=>oauth_callback})
|
9
|
+
session[:request_token] = @request_token.token
|
10
|
+
session[:request_token_secret] = @request_token.secret
|
11
|
+
|
12
|
+
url = @request_token.authorize_url
|
13
|
+
url << "&oauth_callback=#{CGI.escape(SoundcloudAuth.oauth_callback)}" if SoundcloudAuth.oauth_callback?
|
14
|
+
redirect_to url
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def oauth_callback
|
19
|
+
|
20
|
+
unless session[:request_token] && session[:request_token_secret]
|
21
|
+
authentication_failed('No authentication information was found in the session. Please try again.') and return
|
22
|
+
end
|
23
|
+
|
24
|
+
unless params[:oauth_token].blank? || session[:request_token] == params[:oauth_token]
|
25
|
+
authentication_failed('Authentication information does not match session information. Please try again.') and return
|
26
|
+
end
|
27
|
+
|
28
|
+
@request_token = OAuth::RequestToken.new(SoundcloudAuth.consumer, session[:request_token], session[:request_token_secret])
|
29
|
+
|
30
|
+
oauth_verifier = params["oauth_verifier"]
|
31
|
+
@access_token = @request_token.get_access_token(:oauth_verifier => oauth_verifier)
|
32
|
+
|
33
|
+
session[:request_token] = nil
|
34
|
+
session[:request_token_secret] = nil
|
35
|
+
|
36
|
+
puts @access_token
|
37
|
+
|
38
|
+
#@user = User.identify_or_create_from_access_token(@access_token)
|
39
|
+
|
40
|
+
#session[:user_id] = @user.id
|
41
|
+
|
42
|
+
#cookies[:remember_token] = @user.remember_me
|
43
|
+
|
44
|
+
#authentication_succeeded
|
45
|
+
|
46
|
+
rescue Net::HTTPServerException => e
|
47
|
+
case e.message
|
48
|
+
when '401 "Unauthorized"'
|
49
|
+
authentication_failed('This authentication request is no longer valid. Please try again.') and return
|
50
|
+
else
|
51
|
+
authentication_failed('There was a problem trying to authenticate you. Please try again.') and return
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def destroy
|
57
|
+
logout_keeping_session!
|
58
|
+
redirect_back_or_default('/')
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module SoundcloudAuth
|
2
|
+
class GenericUser < ActiveRecord::Base
|
3
|
+
|
4
|
+
attr_protected :soundcloud_id, :remember_token, :remember_token_expires_at
|
5
|
+
|
6
|
+
SOUNDCLOUD_ATTRIBUTES = [
|
7
|
+
:plan,
|
8
|
+
:avatar_url,
|
9
|
+
:website_title,
|
10
|
+
:permalink,
|
11
|
+
:city,
|
12
|
+
:uri,
|
13
|
+
:country,
|
14
|
+
:username,
|
15
|
+
:discogs_name,
|
16
|
+
:website,
|
17
|
+
:full_name,
|
18
|
+
:followers_count,
|
19
|
+
:description,
|
20
|
+
:permalink_url,
|
21
|
+
:followings_count,
|
22
|
+
:track_count,
|
23
|
+
:myspace_name
|
24
|
+
]
|
25
|
+
|
26
|
+
with_options :if => :utilize_default_validations do |v|
|
27
|
+
v.validates_presence_of :soundcloud_id
|
28
|
+
v.validates_uniqueness_of :soundcloud_id, :message => "ID has already been taken."
|
29
|
+
v.validates_uniqueness_of :remember_token, :allow_blank => true
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.table_name; 'users' end
|
33
|
+
|
34
|
+
def self.new_from_soundcloud_hash(hash)
|
35
|
+
|
36
|
+
raise ArgumentError, 'Invalid hash: must include id.' unless hash.key?('id')
|
37
|
+
|
38
|
+
user = User.new
|
39
|
+
user.soundcloud_id = hash['id'].to_s
|
40
|
+
|
41
|
+
SOUNDCLOUD_ATTRIBUTES.each do |att|
|
42
|
+
user.send("#{att}=", hash[att.to_s]) if user.respond_to?("#{att}=")
|
43
|
+
end
|
44
|
+
|
45
|
+
user
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.from_remember_token(token)
|
50
|
+
first(:conditions => ["remember_token = ? AND remember_token_expires_at > ?", token, Time.now])
|
51
|
+
end
|
52
|
+
|
53
|
+
def assign_soundcloud_attributes(hash)
|
54
|
+
SOUNDCLOUD_ATTRIBUTES.each do |att|
|
55
|
+
send("#{att}=", hash[att.to_s]) if respond_to?("#{att}=")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def update_soundcloud_attributes(hash)
|
60
|
+
assign_soundcloud_attributes(hash)
|
61
|
+
save
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.identify_or_create_from_access_token(token, secret=nil)
|
65
|
+
|
66
|
+
raise ArgumentError, 'Must authenticate with an OAuth::AccessToken or the string access token and secret.' unless (token && secret) || token.is_a?(OAuth::AccessToken)
|
67
|
+
|
68
|
+
token = OAuth::AccessToken.new(SoundcloudAuth.consumer, token, secret) unless token.is_a?(OAuth::AccessToken)
|
69
|
+
|
70
|
+
user_info = JSON.parse(token.get(SoundcloudAuth.path_prefix + '/me.json'))
|
71
|
+
|
72
|
+
if user = User.find_by_soundcloud_id(user_info['id'].to_s)
|
73
|
+
user.assign_soundcloud_attributes(user_info)
|
74
|
+
user.access_token = token.token
|
75
|
+
user.access_secret = token.secret
|
76
|
+
user.save
|
77
|
+
user
|
78
|
+
else
|
79
|
+
User.create_from_soundcloud_hash_and_token(user_info, token)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.create_from_soundcloud_hash_and_token(user_info, access_token)
|
85
|
+
user = User.new_from_soundcloud_hash(user_info)
|
86
|
+
user.access_token = access_token.token
|
87
|
+
user.access_secret = access_token.secret
|
88
|
+
user.save
|
89
|
+
user
|
90
|
+
end
|
91
|
+
|
92
|
+
def utilize_default_validations
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
def soundcloud
|
97
|
+
# OAuth::AccessToken.new(TwitterAuth.consumer, access_token, access_secret)
|
98
|
+
end
|
99
|
+
|
100
|
+
def remember_me
|
101
|
+
|
102
|
+
return false unless respond_to?(:remember_token)
|
103
|
+
|
104
|
+
self.remember_token = ActiveSupport::SecureRandom.hex(10)
|
105
|
+
self.remember_token_expires_at = Time.now + SoundcloudAuth.remember_for.days
|
106
|
+
|
107
|
+
save
|
108
|
+
|
109
|
+
{:value => self.remember_token, :expires => self.remember_token_expires_at}
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
def forget_me
|
114
|
+
self.remember_token = self.remember_token_expires_at = nil
|
115
|
+
self.save
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
ActionController::Routing::Routes.draw do |map|
|
2
|
+
map.login '/login', :controller => 'sessions', :action => 'new'
|
3
|
+
map.logout '/logout', :controller => 'sessions', :action => 'destroy'
|
4
|
+
map.resource :session
|
5
|
+
map.oauth_callback '/oauth_callback', :controller => 'sessions', :action => 'oauth_callback'
|
6
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
SoundcloudAuth Generator
|
2
|
+
=====================
|
3
|
+
|
4
|
+
The SoundcloudAuth generator allows you to generate the components necessary to implement SoundCloud as a Single Sign-On provider for your site.
|
5
|
+
|
6
|
+
To run it, you simply need to call it:
|
7
|
+
|
8
|
+
script/generate soundcloud_auth
|
9
|
+
|
10
|
+
This will generate the migration necessary for the users table as well as generate a User model that extends the appropriate SoundcloudAuth model template and a config/soundcloud_auth.yml that allows you to set your OAuth consumer key and secret.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class SoundcloudAuthGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
def manifest
|
4
|
+
record do |m|
|
5
|
+
m.class_collisions 'User'
|
6
|
+
|
7
|
+
m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => 'soundcloud_auth_migration'
|
8
|
+
m.template 'user.rb', File.join('app','models','user.rb')
|
9
|
+
m.template 'soundcloud_auth.yml', File.join('config','soundcloud_auth.yml')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class SoundcloudAuthMigration < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :users do |t|
|
4
|
+
|
5
|
+
t.string :soundcloud_id
|
6
|
+
t.string :username
|
7
|
+
t.string :access_token
|
8
|
+
t.string :access_secret
|
9
|
+
|
10
|
+
t.string :remember_token
|
11
|
+
t.datetime :remember_token_expires_at
|
12
|
+
|
13
|
+
# This information is automatically kept
|
14
|
+
# in-sync at each login of the user. You
|
15
|
+
# may remove any/all of these columns.
|
16
|
+
|
17
|
+
t.string :plan
|
18
|
+
t.string :avatar_url
|
19
|
+
t.string :website_title
|
20
|
+
t.string :permalink
|
21
|
+
t.string :city
|
22
|
+
t.string :uri
|
23
|
+
t.string :country
|
24
|
+
t.string :discogs_name
|
25
|
+
t.string :website
|
26
|
+
t.string :full_name
|
27
|
+
t.integer :followers_count
|
28
|
+
t.string :description
|
29
|
+
t.string :permalink_url
|
30
|
+
t.integer :followings_count
|
31
|
+
t.integer :track_count
|
32
|
+
t.string :myspace_name
|
33
|
+
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.down
|
39
|
+
drop_table :users
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
development:
|
2
|
+
key: devkey
|
3
|
+
secret: devsecret
|
4
|
+
base_url: "http://api.soundcloud.com"
|
5
|
+
remember_for: 14 # days
|
6
|
+
oauth_callback: "http://localhost:3000/oauth_callback"
|
7
|
+
test:
|
8
|
+
key: testkey
|
9
|
+
secret: testsecret
|
10
|
+
base_url: "http://api.soundcloud.com"
|
11
|
+
remember_for: 14 # days
|
12
|
+
oauth_callback: "http://localhost:3000/oauth_callback"
|
13
|
+
production:
|
14
|
+
key: prodkey
|
15
|
+
secret: prodsecret
|
16
|
+
base_url: "http://api.soundcloud.com"
|
17
|
+
remember_for: 14 # days
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/rails/init'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module SoundcloudAuth
|
2
|
+
class Error < StandardError; end
|
3
|
+
|
4
|
+
def self.config(environment=RAILS_ENV)
|
5
|
+
@config ||= {}
|
6
|
+
@config[environment] ||= YAML.load(File.open(RAILS_ROOT + '/config/soundcloud_auth.yml').read)[environment]
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.base_url
|
10
|
+
config['base_url'] || 'http://api.soundcloud.com'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.path_prefix
|
14
|
+
URI.parse(base_url).path
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.oauth_callback?
|
18
|
+
config.key?('oauth_callback')
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.oauth_callback
|
22
|
+
config['oauth_callback']
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.remember_for
|
26
|
+
(config['remember_for'] || 14).to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.consumer
|
30
|
+
|
31
|
+
options = {
|
32
|
+
:site => TwitterAuth.base_url,
|
33
|
+
:request_token_path => "/oauth/request_token",
|
34
|
+
:access_token_path => "/oauth/access_token",
|
35
|
+
:authorize_path => "/oauth/authorize"
|
36
|
+
}
|
37
|
+
|
38
|
+
OAuth::Consumer.new(
|
39
|
+
config['key'],
|
40
|
+
config['secret'],
|
41
|
+
options
|
42
|
+
)
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
=end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
require 'soundcloud_auth/controller_extensions'
|
51
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module SoundcloudAuth
|
2
|
+
# These methods borrow HEAVILY from Rick Olsen's
|
3
|
+
# Restful Authentication. All cleverness props
|
4
|
+
# go to him, not me.
|
5
|
+
module ControllerExtensions
|
6
|
+
def self.included(base)
|
7
|
+
base.send :helper_method, :current_user, :logged_in?, :authorized?
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def authentication_failed(message, destination='/')
|
13
|
+
flash[:error] = message
|
14
|
+
redirect_to destination
|
15
|
+
end
|
16
|
+
|
17
|
+
def authentication_succeeded(message = 'You have logged in successfully.', destination = '/')
|
18
|
+
flash[:notice] = message
|
19
|
+
redirect_back_or_default destination
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_user
|
23
|
+
@current_user ||=
|
24
|
+
if session[:user_id]
|
25
|
+
User.find_by_id(session[:user_id])
|
26
|
+
elsif cookies[:remember_token]
|
27
|
+
User.from_remember_token(cookies[:remember_token])
|
28
|
+
else
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def current_user=(new_user)
|
34
|
+
session[:user_id] = new_user.id
|
35
|
+
@current_user = new_user
|
36
|
+
end
|
37
|
+
|
38
|
+
def authorized?
|
39
|
+
!!current_user
|
40
|
+
end
|
41
|
+
|
42
|
+
def login_required
|
43
|
+
authorized? || access_denied
|
44
|
+
end
|
45
|
+
|
46
|
+
def access_denied
|
47
|
+
store_location
|
48
|
+
redirect_to login_path
|
49
|
+
end
|
50
|
+
|
51
|
+
def store_location
|
52
|
+
session[:return_to] = request.request_uri
|
53
|
+
end
|
54
|
+
|
55
|
+
def redirect_back_or_default(default)
|
56
|
+
redirect_to(session[:return_to] || default)
|
57
|
+
session[:return_to] = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def logged_in?
|
61
|
+
!!current_user
|
62
|
+
end
|
63
|
+
|
64
|
+
def logout_keeping_session!
|
65
|
+
session[:user_id] = nil
|
66
|
+
@current_user = nil
|
67
|
+
cookies.delete(:remember_token)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
ActionController::Base.send(:include, SoundcloudAuth::ControllerExtensions)
|
data/rails/init.rb
ADDED
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: soundcloud-auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Lee Martin
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-06-25 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: oauth
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 17
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 3
|
33
|
+
- 1
|
34
|
+
version: 0.3.1
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: SoundcloudAuth is a Rails plugin gem that provides Single Sign-On capabilities for Rails applications via SoundCloud.
|
38
|
+
email: lee@soundcloud.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files:
|
44
|
+
- README.markdown
|
45
|
+
files:
|
46
|
+
- README.markdown
|
47
|
+
- Rakefile
|
48
|
+
- VERSION
|
49
|
+
- app/controllers/sessions_controller.rb
|
50
|
+
- app/models/soundcloud_auth/generic_user.rb
|
51
|
+
- config/routes.rb
|
52
|
+
- generators/soundcloud_auth/USAGE
|
53
|
+
- generators/soundcloud_auth/soundcloud_auth_generator.rb
|
54
|
+
- generators/soundcloud_auth/templates/migration.rb
|
55
|
+
- generators/soundcloud_auth/templates/soundcloud_auth.yml
|
56
|
+
- generators/soundcloud_auth/templates/user.rb
|
57
|
+
- init.rb
|
58
|
+
- lib/soundcloud_auth.rb
|
59
|
+
- lib/soundcloud_auth/controller_extensions.rb
|
60
|
+
- rails/init.rb
|
61
|
+
has_rdoc: true
|
62
|
+
homepage: http://github.com/leemartin/soundcloud-auth
|
63
|
+
licenses: []
|
64
|
+
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options:
|
67
|
+
- --charset=UTF-8
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.3.7
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: SoundcloudAuth is a Rails plugin gem that provides Single Sign-On capabilities for Rails applications via SoundCloud.
|
95
|
+
test_files: []
|
96
|
+
|