muck-auth 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +5 -0
- data/Rakefile +72 -0
- data/VERSION +1 -0
- data/app/controllers/muck/authentications_controller.rb +55 -0
- data/app/helpers/muck_auth_helper.rb +10 -0
- data/app/views/authentications/_available_services.html.erb +12 -0
- data/app/views/authentications/_current_services.html.erb +15 -0
- data/app/views/authentications/failure.html.erb +1 -0
- data/app/views/authentications/index.html.erb +8 -0
- data/app/views/authentications/signup.html.erb +41 -0
- data/config/locales/en.yml +57 -0
- data/config/routes.rb +5 -0
- data/lib/muck-auth.rb +6 -0
- data/lib/muck-auth/config.rb +22 -0
- data/lib/muck-auth/engine.rb +34 -0
- data/lib/muck-auth/exceptions.rb +5 -0
- data/lib/muck-auth/models/authentication.rb +25 -0
- data/lib/muck-auth/models/user.rb +23 -0
- data/lib/tasks/muck_auth.rake +13 -0
- data/muck-auth.gemspec +74 -0
- data/muck-oauth.gemspec +2032 -0
- metadata +159 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009-2010 Tatemae.com
|
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
data/Rakefile
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc 'Default: run specs.'
|
7
|
+
task :default => :spec
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
9
|
+
t.rspec_opts = ["--color", "-c", "-f progress", "-r test/spec/spec_helper.rb"]
|
10
|
+
t.pattern = 'test/spec/**/*_spec.rb'
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
gem.name = "muck-auth"
|
17
|
+
gem.summary = %Q{OAuth for muck}
|
18
|
+
gem.description = %Q{A simple wrapper for the omniauth gem so that it is faster to include oauth in muck based applications.}
|
19
|
+
gem.email = "justin@tatemae.com"
|
20
|
+
gem.homepage = "http://github.com/tatemae/muck-auth"
|
21
|
+
gem.authors = ["Justin Ball"]
|
22
|
+
gem.add_dependency "omniauth"
|
23
|
+
gem.add_dependency "overlord"
|
24
|
+
gem.add_dependency "muck-engine"
|
25
|
+
gem.add_dependency "muck-users"
|
26
|
+
gem.add_development_dependency "babelphish"
|
27
|
+
gem.files.exclude 'test/**'
|
28
|
+
gem.test_files.exclude 'test/**' # exclude test directory
|
29
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
30
|
+
end
|
31
|
+
Jeweler::GemcutterTasks.new
|
32
|
+
rescue LoadError
|
33
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
34
|
+
end
|
35
|
+
|
36
|
+
begin
|
37
|
+
require 'rcov/rcovtask'
|
38
|
+
Rcov::RcovTask.new do |t|
|
39
|
+
#t.libs << 'lib'
|
40
|
+
t.libs << 'test/lib'
|
41
|
+
t.pattern = 'test/test/**/*_spec.rb'
|
42
|
+
t.verbose = true
|
43
|
+
t.output_dir = 'coverage'
|
44
|
+
t.rcov_opts << '--exclude "gems/*"'
|
45
|
+
end
|
46
|
+
rescue LoadError
|
47
|
+
task :rcov do
|
48
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'rake/rdoctask'
|
53
|
+
desc 'Generate documentation for the muck-auth gem.'
|
54
|
+
Rake::RDocTask.new do |rdoc|
|
55
|
+
if File.exist?('VERSION.yml')
|
56
|
+
config = YAML.load(File.read('VERSION.yml'))
|
57
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
58
|
+
else
|
59
|
+
version = ""
|
60
|
+
end
|
61
|
+
|
62
|
+
rdoc.rdoc_dir = 'rdoc'
|
63
|
+
rdoc.title = "muck_auth #{version}"
|
64
|
+
rdoc.rdoc_files.include('README*')
|
65
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Translate this gem'
|
69
|
+
task :translate do
|
70
|
+
file = File.join(File.dirname(__FILE__), 'config', 'locales', 'en.yml')
|
71
|
+
system("babelphish -o -y #{file}")
|
72
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.1.0
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Muck::AuthenticationsController < ApplicationController
|
2
|
+
def index
|
3
|
+
@current_authentications = current_user.authentications if current_user
|
4
|
+
if @current_authentications
|
5
|
+
@unused_authentications = Authentication.unused_services(@current_authentications)
|
6
|
+
else
|
7
|
+
@unused_authentications = Authentication.all_services
|
8
|
+
end
|
9
|
+
respond_to do |format|
|
10
|
+
format.html { render :template => 'authentications/index' }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
@omniauth = request.env["omniauth.auth"]
|
16
|
+
# Associated the account with the user
|
17
|
+
if current_user
|
18
|
+
current_user.authentications.create!(:provider => @omniauth['provider'], :uid => @omniauth['uid'], :raw_auth => @omniauth.to_json)
|
19
|
+
flash[:notice] = t('muck.auth.authentication_success')
|
20
|
+
redirect_to authentications_url
|
21
|
+
# Try to log the user in via the service
|
22
|
+
elsif authentication = Authentication.find_by_provider_and_uid(@omniauth['provider'], @omniauth['uid'])
|
23
|
+
flash[:notice] = t('muck.users.login_success')
|
24
|
+
UserSession.create(authentication.user)
|
25
|
+
# Could not find any information. Create a new account.
|
26
|
+
else
|
27
|
+
@user = User.new
|
28
|
+
@user.apply_omniauth(@omniauth)
|
29
|
+
@user.generate_password
|
30
|
+
if @user.save
|
31
|
+
UserSession.create(@user)
|
32
|
+
flash[:notice] = t('muck.users.thanks_sign_up')
|
33
|
+
signup_complete_path(@user)
|
34
|
+
else
|
35
|
+
# Have to build a new user to get rid of the password
|
36
|
+
@user = User.new
|
37
|
+
@user.apply_omniauth(@omniauth)
|
38
|
+
render :template => 'authentications/signup'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def failure
|
44
|
+
respond_to do |format|
|
45
|
+
format.html { render :template => 'authentications/failure' }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def destroy
|
50
|
+
@authentication = current_user.authentications.find(params[:id])
|
51
|
+
@authentication.destroy
|
52
|
+
flash[:notice] = t('muck.auth.removed_authentication')
|
53
|
+
redirect_to authentications_url
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div id="auth_available_services" class="auth-services">
|
2
|
+
<% unless authentications.empty? %>
|
3
|
+
<h3><%=translate('muck.auth.you_can_connect_to_the_following_services') %></h3>
|
4
|
+
<ul <%='class="icon-list"' if include_icons%>>
|
5
|
+
<% authentications.each do |authentication| -%>
|
6
|
+
<li class="<%=authentication.to_s.parameterize%> auth_service service-link" <%= service_icon_background(authentication) if include_icons%> title="<%=translate('muck.auth.connect_to_account_title', :service => authentication.to_s.humanize) %>">
|
7
|
+
<%= link_to auth_service_name(authentication), "/auth/#{authentication}" %>
|
8
|
+
</li>
|
9
|
+
<% end -%>
|
10
|
+
</ul>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<div id="auth_current_services" class="auth-services">
|
2
|
+
<% if authentications.empty? -%>
|
3
|
+
<p><%=translate('muck.oauth.you_are_currently_not_connected_to_any_external_services') %></p>
|
4
|
+
<% else -%>
|
5
|
+
<p><%=translate('muck.oauth.you_are_connected_to_the_following_services') %></p>
|
6
|
+
<ul <%='class="icon-list"' if include_icons%>>
|
7
|
+
<% authentications.each do |authentication| -%>
|
8
|
+
<li class="<%=token.class.service_name.to_s.parameterize%> oauth_service service-link" <%= service_icon_background(token.class.service_name) if include_icons %>>
|
9
|
+
<%= link_to auth_service_name(authentication.provider), oauth_consumer_path(token.class.service_name), :class => 'authfancybox' %>
|
10
|
+
<%= link_to "X", authentication, :confirm => 'Are you sure you want to remove this authentication option?', :method => :delete, :class => "remove" %>
|
11
|
+
</li>
|
12
|
+
<% end -%>
|
13
|
+
</ul>
|
14
|
+
<% end -%>
|
15
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%=translate('muck.auth.auth_connect_error') %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<h1><%=translate('muck.auth.services') %></h1>
|
2
|
+
<% if @authentications %>
|
3
|
+
<%= render 'authentications/current_services', :authentications => @current_authentications %>
|
4
|
+
<p><strong>Add another service to sign in with:</strong></p>
|
5
|
+
<% else %>
|
6
|
+
<p><strong>Sign in through one of these services:</strong></p>
|
7
|
+
<% end %>
|
8
|
+
<%= render 'authentications/available_services', :authentications => @unused_authentications, :include_icons => true %>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<%= muck_form_for @user, :url => users_path, :html => {:id => "register-user-form", :name => 'register-user-form'} do |f| -%>
|
2
|
+
|
3
|
+
<%= t('muck.auth.sign_up_prompt') %>
|
4
|
+
|
5
|
+
<% if MuckUsers.configuration.require_access_code -%>
|
6
|
+
<%= f.text_field :access_code_code, { :label => translate('muck.users.access_code'),
|
7
|
+
:extra_html => translate('muck.users.access_code_help',
|
8
|
+
:access_request_anchor => %Q{<a class="fancy-pop iframe" href="#{new_access_code_request_path}">},
|
9
|
+
:access_request_anchor_end => "</a>").html_safe } -%>
|
10
|
+
<% end -%>
|
11
|
+
|
12
|
+
<%= f.text_field :login, { :label => t('muck.users.choose_member_name'),
|
13
|
+
:extra_html => '',
|
14
|
+
:tip => t('muck.users.username_help'),
|
15
|
+
:required_label => t('muck.users.username') } -%>
|
16
|
+
<%= f.text_field :email, { :label => t('muck.users.email_address'),
|
17
|
+
:tip => t('muck.users.email_help'),
|
18
|
+
:extra_html => '' } -%>
|
19
|
+
<%= f.password_field :password, { :label => t('muck.users.password'),
|
20
|
+
:tip => t('muck.users.password_help')} -%>
|
21
|
+
<%= f.password_field :password_confirmation, { :label => t('muck.users.confirm_password'),
|
22
|
+
:tip => t('muck.users.password_confirmation_help') } -%>
|
23
|
+
|
24
|
+
<% if MuckUsers.configuration.validate_terms_of_service -%>
|
25
|
+
<div class="checklist">
|
26
|
+
<%= f.check_box :terms_of_service, { :label => t('muck.users.terms_and_service', :tos_link_anchor => '<a href="/terms_of_service">', :link_end => '</a>').html_safe,
|
27
|
+
:tip => t('muck.users.terms_and_service_tip') } -%>
|
28
|
+
</div>
|
29
|
+
<% end -%>
|
30
|
+
|
31
|
+
<%= f.fields_for :authentications do |af| -%>
|
32
|
+
<%= af.hidden_field :provider %>
|
33
|
+
<%= af.hidden_field :uid %>
|
34
|
+
<%= af.hidden_field :raw_auth %>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<div class="button form-row">
|
38
|
+
<%= f.submit t('muck.users.sign_up_now') %>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<% end -%>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
muck:
|
4
|
+
auth:
|
5
|
+
problem_creating_account: "There was a problem creating your account."
|
6
|
+
removed_authentication: Successfully removed authentication.
|
7
|
+
authentication_success: Authentication successful.
|
8
|
+
you_can_connect_to_the_following_services: "You can connect to the following services:"
|
9
|
+
auth_connect_error: An error occurred while trying to connect to the service.
|
10
|
+
sign_up_prompt: In order to continue please provide the information below.
|
11
|
+
back: Back
|
12
|
+
do_you_have_an_application_to_register: Do you have an application you would like to register for use with us using the %{link} standard?
|
13
|
+
support_url_label: Support URL
|
14
|
+
updated_successfully: Updated the client information successfully
|
15
|
+
reconnect: Reconnect
|
16
|
+
you_are_currently_not_connected_to_any_external_services: You are currently not connected to any external services.
|
17
|
+
edit: Edit
|
18
|
+
are_you_sure: Are you sure?
|
19
|
+
delete: Delete
|
20
|
+
issued: Issued
|
21
|
+
main_application_label: Main Application URL*
|
22
|
+
destroyed_successfully: Destroyed the client application registration
|
23
|
+
connect_to_account_title: Connect to your %{service} account
|
24
|
+
or: or
|
25
|
+
register_a_new_application: Register a new application
|
26
|
+
register: Register
|
27
|
+
register_your_application: Register your application
|
28
|
+
application_developers: Application Developers
|
29
|
+
name_label: Name*
|
30
|
+
request_allowed: You have allowed this request
|
31
|
+
authorize_access_question: Would you like to authorize %{name}} (%{link}) to access your account?
|
32
|
+
you_are_already_connected_to: You are already Connected to %{service}
|
33
|
+
request_token_url: Request Token URL
|
34
|
+
application: Application
|
35
|
+
back_label: Back
|
36
|
+
callback_label: Callback URL*
|
37
|
+
authorize_access_label: authorize access
|
38
|
+
registered_successfully: Registered the information successfully
|
39
|
+
wrong_id: Wrong application id
|
40
|
+
you_are_connected_to_the_following_services: "You are connected to the following services:"
|
41
|
+
authorize_url: Authorize URL
|
42
|
+
access_token_url: Access Token URL
|
43
|
+
tokens_issued: The following tokens have been issued to applications in your name
|
44
|
+
services: Services
|
45
|
+
revoke: Revoke!
|
46
|
+
authorize_access: Authorize access to your account
|
47
|
+
you_have_the_following_client_applications_registered: "You have the following client applications registered:"
|
48
|
+
you_must_register_your_web_application: You must register your web application before it can make OAuth requests to this service
|
49
|
+
show_label: Show
|
50
|
+
edit_label: Edit
|
51
|
+
edit_application: Edit your application
|
52
|
+
disconnect_or_reconnect: "%{disconnect}} or %{reconnect} if you experienced a problem."
|
53
|
+
disconnect: Disconnect
|
54
|
+
we_support_hmac_sha: We support hmac-sha1 (recommended) as well as plain text in ssl mode.
|
55
|
+
consume_secret: "Consumer Secret:"
|
56
|
+
request_disallowed: You have disallowed this request
|
57
|
+
http_result_error: "There was a problem with your request %{error}"
|
data/config/routes.rb
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
resources :authentications, :controller => 'muck/authentications'
|
3
|
+
match '/auth/:provider/callback' => 'muck/authentications#create', :controller => 'muck/authentications'
|
4
|
+
match '/auth/failure' => 'muck/authentications#failure', :controller => 'muck/authentications'
|
5
|
+
end
|
data/lib/muck-auth.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module MuckAuth
|
2
|
+
|
3
|
+
def self.configuration
|
4
|
+
# In case the user doesn't setup a configure block we can always return default settings:
|
5
|
+
@configuration ||= Configuration.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.configure
|
9
|
+
self.configuration ||= Configuration.new
|
10
|
+
yield(configuration)
|
11
|
+
end
|
12
|
+
|
13
|
+
class Configuration
|
14
|
+
|
15
|
+
attr_accessor :auth_credentials
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
self.auth_credentials = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'omniauth/oauth'
|
3
|
+
require 'muck-auth'
|
4
|
+
|
5
|
+
module MuckProfiles
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
|
8
|
+
def muck_name
|
9
|
+
'muck-auth'
|
10
|
+
end
|
11
|
+
|
12
|
+
initializer 'muck_auth.helpers' do |app|
|
13
|
+
ActiveSupport.on_load(:action_view) do
|
14
|
+
include MuckAuthHelper
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
initializer 'muck_auth.i18n' do |app|
|
19
|
+
ActiveSupport.on_load(:i18n) do
|
20
|
+
I18n.load_path += Dir[ File.join(File.dirname(__FILE__), '..', '..', 'config', 'locales', '*.{rb,yml}') ]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
initializer "muck_auth.add_middleware" do |app|
|
25
|
+
raise MuckAuth::Exceptions::InvalidConfiguration, "Please provide a valid configuration for Muck Auth." if MuckAuth.configuration.auth_credentials.blank?
|
26
|
+
MuckAuth.configuration.auth_credentials.each_key do |key|
|
27
|
+
app.middleware.use OmniAuth::Builder do
|
28
|
+
provider key, MuckAuth.configuration.auth_credentials[key]['key'], MuckAuth.configuration.auth_credentials[key]['secret']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# include MuckAuth::Models::MuckAuthentication
|
2
|
+
module MuckAuth
|
3
|
+
module Models
|
4
|
+
module MuckAuthentication
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
belongs_to :user
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def all_services
|
13
|
+
services = []
|
14
|
+
MuckAuth.configuration.auth_credentials.each_key{ |s| services << s }
|
15
|
+
services
|
16
|
+
end
|
17
|
+
def unused_services(current_authentications)
|
18
|
+
all_services.find_all{ |s| !current_authentications.any?{ |c| c.provider == s } }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# include MuckAuth::Models::MuckUser
|
2
|
+
module MuckAuth
|
3
|
+
module Models
|
4
|
+
module MuckUser
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
has_many :authentications
|
9
|
+
accepts_nested_attributes_for :authentications, :allow_destroy => true
|
10
|
+
end
|
11
|
+
|
12
|
+
def apply_omniauth(omniauth)
|
13
|
+
self.email = omniauth['user_info']['email'] if email.blank?
|
14
|
+
authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'], :raw_auth => omniauth.to_json)
|
15
|
+
end
|
16
|
+
|
17
|
+
def password_required?
|
18
|
+
(authentications.empty? || !password.blank?) && super
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|