muck-auth 3.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/.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
|