thincloud-authentication 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +133 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/thincloud/authentication/application.js +15 -0
- data/app/assets/stylesheets/thincloud/authentication/application.css +13 -0
- data/app/controllers/thincloud/authentication/application_controller.rb +6 -0
- data/app/controllers/thincloud/authentication/registrations_controller.rb +90 -0
- data/app/controllers/thincloud/authentication/sessions_controller.rb +23 -0
- data/app/helpers/thincloud/authentication/registrations_helper.rb +9 -0
- data/app/mailers/thincloud/authentication/registrations_mailer.rb +12 -0
- data/app/models/thincloud/authentication/identity.rb +80 -0
- data/app/views/thincloud/authentication/layouts/application.html.erb +14 -0
- data/app/views/thincloud/authentication/registrations/_registration_form.html.erb +69 -0
- data/app/views/thincloud/authentication/registrations/new.html.erb +1 -0
- data/app/views/thincloud/authentication/registrations_mailer/verification_token.text.erb +5 -0
- data/app/views/thincloud/authentication/sessions/_login_form.html.erb +46 -0
- data/app/views/thincloud/authentication/sessions/new.html.erb +22 -0
- data/config/routes.rb +14 -0
- data/db/migrate/20120918233329_create_thincloud_authentication_identities.rb +19 -0
- data/lib/tasks/thincloud-authentication_tasks.rake +4 -0
- data/lib/thincloud-authentication.rb +9 -0
- data/lib/thincloud/authentication/authenticatable_controller.rb +64 -0
- data/lib/thincloud/authentication/configuration.rb +20 -0
- data/lib/thincloud/authentication/engine.rb +67 -0
- data/lib/thincloud/authentication/identifiable_user.rb +9 -0
- data/lib/thincloud/authentication/version.rb +5 -0
- metadata +287 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 New Leaders
|
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.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
# Thincloud::Authentication
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/newleaders/thincloud-authentication.png)](http://travis-ci.org/newleaders/thincloud-authentication) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/newleaders/thincloud-authentication)
|
4
|
+
|
5
|
+
## Description
|
6
|
+
|
7
|
+
A Rails Engine to provide authentication for Thincloud applications.
|
8
|
+
|
9
|
+
## Requirements
|
10
|
+
|
11
|
+
This gem requires Rails 3.2+ and has been tested on the following versions:
|
12
|
+
|
13
|
+
* 3.2
|
14
|
+
|
15
|
+
This gem has been tested against the following Ruby versions:
|
16
|
+
|
17
|
+
* MRI 1.9.2
|
18
|
+
* MRI 1.9.3
|
19
|
+
* JRuby 1.6+ (with `JRUBY_OPTS=--1.9`)
|
20
|
+
* Rubinius 2.0.0dev (with `RBXOPT=-X19`)
|
21
|
+
|
22
|
+
This gem has been tested against the following database versions:
|
23
|
+
|
24
|
+
* MySQL 5.0, 5.5
|
25
|
+
* PostgreSQL 9.1, 9.2
|
26
|
+
* SQLite 3
|
27
|
+
|
28
|
+
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
Add this line to your application's Gemfile:
|
32
|
+
|
33
|
+
``` ruby
|
34
|
+
gem "thincloud-authentication"
|
35
|
+
```
|
36
|
+
|
37
|
+
* Run `bundle`
|
38
|
+
* Copy the migrations and prepare your databases:
|
39
|
+
|
40
|
+
```
|
41
|
+
$ rake thincloud_authentication:install:migrations db:migrate db:test:prepare
|
42
|
+
```
|
43
|
+
|
44
|
+
* Mount the engine in your `config/routes.rb` file:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
mount Thincloud::Authentication::Engine => "/auth", as: "auth_engine"
|
48
|
+
```
|
49
|
+
|
50
|
+
Using the example above, you may now login or signup at [http://lvh.me:3000/auth](http://lvh.me:3000/auth).
|
51
|
+
|
52
|
+
### Prerequisites
|
53
|
+
|
54
|
+
The following must be true for `thincloud-authentication` to operate properly:
|
55
|
+
|
56
|
+
* A `root_url` must be defined in `config/routes.rb`
|
57
|
+
* A `User` model must exist
|
58
|
+
|
59
|
+
|
60
|
+
## Configuration
|
61
|
+
|
62
|
+
The `Thincloud::Authentication` module accepts a `configure` block with options to customize the engine behavior.
|
63
|
+
|
64
|
+
|
65
|
+
### Mailers
|
66
|
+
|
67
|
+
Set the `mailer_sender` option to customize the "From" address of the emails sent from the system:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Thincloud::Authentication.configure do |config|
|
71
|
+
config.mailer_sender = "app@example.com"
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
|
76
|
+
### Additional provider strategies
|
77
|
+
|
78
|
+
Add a key to the `providers` hash with the name of the strategy, followed by additional options for `scopes` and `fields` as needed. Additionally, you will need to provide environment variables (prefixed with the provider name), with the `consumer_key` and `consumer_secret` values from your OAuth provider.
|
79
|
+
|
80
|
+
To enable the [LinkedIn](https://github.com/skorks/omniauth-linkedin) provider:
|
81
|
+
|
82
|
+
* Provide values for `ENV["LINKEDIN_CONSUMER_KEY"]` and `ENV["LINKEDIN_CONSUMER_SECRET"]`
|
83
|
+
* Add the file `config/initializers/thincloud_authentication.rb` with the following contents:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
Thincloud::Authentication.configure do |config|
|
87
|
+
config.providers[:linkedin] = {
|
88
|
+
scopes: "r_emailaddress r_basicprofile",
|
89
|
+
fields: ["id", "email-address", "first-name", "last-name", "headline",
|
90
|
+
"industry", "picture-url", "location", "public-profile-url"]
|
91
|
+
}
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
|
96
|
+
### Vanity Routes
|
97
|
+
|
98
|
+
If you want to customize the routes (remove the `/auth` prefix), you may add the following to your `config/routes.rb` file:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
get "signup", to: "thincloud/authentication/registrations#new", as: "signup"
|
102
|
+
get "login", to: "thincloud/authentication/sessions#new", as: "login"
|
103
|
+
delete "logout", to: "thincloud/authentication/sessions#destroy", as: "logout"
|
104
|
+
```
|
105
|
+
|
106
|
+
Using the example above, you will have the following routes locally:
|
107
|
+
|
108
|
+
* `signup_url` points to "/signup"
|
109
|
+
* `login_url` points to "/login"
|
110
|
+
* `logout_url` points to "/logout" - Make sure to use the `delete` method to logout.
|
111
|
+
|
112
|
+
|
113
|
+
## TODO
|
114
|
+
|
115
|
+
* Add "forgot password" functionality
|
116
|
+
* Add multiple, configurable strategy options
|
117
|
+
* Add a configuration option to customize the mailers
|
118
|
+
|
119
|
+
|
120
|
+
## Contributing
|
121
|
+
|
122
|
+
1. [Fork it](https://github.com/newleaders/thincloud-authentication/fork_select)
|
123
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
124
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
125
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
126
|
+
5. [Create a Pull Request](https://github.com/newleaders/thincloud-authentication/pull/new)
|
127
|
+
|
128
|
+
|
129
|
+
## License
|
130
|
+
|
131
|
+
* Freely distributable and licensed under the [MIT license](http://newleaders.mit-license.org/2012/license.html).
|
132
|
+
* Copyright (c) 2012 New Leaders ([opensource@newleaders.com](opensource@newleaders.com))
|
133
|
+
* [https://newleaders.com](https://newleaders.com)
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Thincloud::Authentication'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require_dependency "thincloud/authentication/application_controller"
|
2
|
+
|
3
|
+
module Thincloud::Authentication
|
4
|
+
# Public: Handle OmniAuth callbacks.
|
5
|
+
class RegistrationsController < ApplicationController
|
6
|
+
before_filter :extract_identity, only: :create
|
7
|
+
|
8
|
+
def new
|
9
|
+
@identity = Identity.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
# identity exists
|
14
|
+
if @identity.present?
|
15
|
+
login_as @identity.user
|
16
|
+
redirect_to main_app.root_url, notice: "You have been logged in."
|
17
|
+
# new identity for current_user
|
18
|
+
elsif current_user
|
19
|
+
add_omniauth_identity_to_current_user
|
20
|
+
redirect_to main_app.root_url, notice: "You have been logged in."
|
21
|
+
# failed identity login
|
22
|
+
elsif invalid_identity_credentials?
|
23
|
+
redirect_to auth_failure_url message: "invalid_credentials",
|
24
|
+
strategy: "identity"
|
25
|
+
# create a new identity
|
26
|
+
else
|
27
|
+
@identity = create_identity_from_request
|
28
|
+
render :new and return if @identity.errors.any?
|
29
|
+
|
30
|
+
if omniauth
|
31
|
+
login_as @identity.user
|
32
|
+
else
|
33
|
+
RegistrationsMailer.verification_token(@identity).deliver
|
34
|
+
flash[:alert] = "Check your email to verify your registration."
|
35
|
+
end
|
36
|
+
redirect_to main_app.root_url
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def verify
|
41
|
+
identity = Identity.verify!(params[:token])
|
42
|
+
login_as identity.user
|
43
|
+
redirect_to main_app.root_url,
|
44
|
+
notice: "Thank you! Your registration has been verified."
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Private: Accessor for OmniAuth environment.
|
50
|
+
#
|
51
|
+
# Returns: An instance of `OmniAuth::InfoHash` or `nil`.
|
52
|
+
def omniauth
|
53
|
+
request.env["omniauth.auth"]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Private: Set an instance varible if an `Identity` if present.
|
57
|
+
#
|
58
|
+
# Returns: An instance of `Identity` or `nil`.
|
59
|
+
def extract_identity
|
60
|
+
@identity = Identity.find_omniauth(omniauth) if omniauth
|
61
|
+
end
|
62
|
+
|
63
|
+
# Private: Determine if the request is from an invalid Identity login.
|
64
|
+
#
|
65
|
+
# Returns: Boolean.
|
66
|
+
def invalid_identity_credentials?
|
67
|
+
params[:provider] == "identity" && params.has_key?(:auth_key)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Private: Add a new identity to the `current_user` from OmniAuth.
|
71
|
+
#
|
72
|
+
# Returns: Boolean.
|
73
|
+
def add_omniauth_identity_to_current_user
|
74
|
+
current_user.identities.build.apply_omniauth(omniauth).save
|
75
|
+
end
|
76
|
+
|
77
|
+
# Private: Create a new identity from submitted params or OmniAuth.
|
78
|
+
#
|
79
|
+
# Returns: An instance of `Identity`.
|
80
|
+
def create_identity_from_request
|
81
|
+
# params[:identity] exists when creating a local identity provider
|
82
|
+
Identity.new(params[:identity]).tap do |identity|
|
83
|
+
identity.user = User.create
|
84
|
+
# omniauth exists if coming from a 3rd party provider like LinkedIn
|
85
|
+
identity.apply_omniauth(omniauth) if omniauth
|
86
|
+
identity.save
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_dependency "thincloud/authentication/application_controller"
|
2
|
+
|
3
|
+
module Thincloud::Authentication
|
4
|
+
# Public: Handle login/logout behavior.
|
5
|
+
class SessionsController < ApplicationController
|
6
|
+
before_filter :authenticate!, only: [:authenticated]
|
7
|
+
|
8
|
+
def new
|
9
|
+
redirect_to main_app.root_url if logged_in?
|
10
|
+
@identity = Identity.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def destroy
|
14
|
+
logout
|
15
|
+
redirect_to main_app.root_url, notice: "You have been logged out."
|
16
|
+
end
|
17
|
+
|
18
|
+
def authenticated
|
19
|
+
# dummy method to test the :authenticate! before_filter
|
20
|
+
render text: "Authenticated!"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Thincloud::Authentication
|
2
|
+
# Public: Email methods for Registration events
|
3
|
+
class RegistrationsMailer < ActionMailer::Base
|
4
|
+
default from: Thincloud::Authentication.configuration.mailer_sender
|
5
|
+
|
6
|
+
# New registration verification token
|
7
|
+
def verification_token(identity)
|
8
|
+
@identity = identity
|
9
|
+
mail to: @identity.email, subject: "Identity Verification"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Thincloud::Authentication
|
2
|
+
# Public: This class represents a User identity (name, email, login provider)
|
3
|
+
class Identity < ::OmniAuth::Identity::Models::ActiveRecord
|
4
|
+
belongs_to :user
|
5
|
+
|
6
|
+
# Limit the ability to mass-assign sensitive fields.
|
7
|
+
attr_accessible :name, :email, :password, :password_confirmation
|
8
|
+
|
9
|
+
validates :name, presence: true
|
10
|
+
validates :email, presence: true, uniqueness: true, format: /@/
|
11
|
+
|
12
|
+
# Ensure that a `verification_token` exists for new records.
|
13
|
+
after_initialize do
|
14
|
+
self.verification_token = SecureRandom.urlsafe_base64 if new_record?
|
15
|
+
end
|
16
|
+
|
17
|
+
# Only validate password if the 'provider' is 'identity'.
|
18
|
+
before_validation do
|
19
|
+
self.password_digest = 0 unless provider == "identity"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Public: Use a helpful attribute name when displaying errors.
|
23
|
+
def self.human_attribute_name(attr, options={})
|
24
|
+
attr == :password_digest ? "Password" : super
|
25
|
+
end
|
26
|
+
|
27
|
+
# Public: Find an `Identity` by OmniAuth parameters.
|
28
|
+
#
|
29
|
+
# omniauth - An instance of `OmniAuth::AuthHash`
|
30
|
+
#
|
31
|
+
# Returns: An instance of `Identity` or `nil`.
|
32
|
+
def self.find_omniauth(omniauth)
|
33
|
+
find_by_provider_and_uid omniauth["provider"], omniauth["uid"]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Public: Mark the `Identity` as having been verified.
|
37
|
+
#
|
38
|
+
# token - A String containing the `verification_token` to look up.
|
39
|
+
#
|
40
|
+
# Returns: An instance of the found `Identity`.
|
41
|
+
# Raises: ActiveRecord::RecordNotFound if the `token` cannot be retrieved.
|
42
|
+
def self.verify!(token)
|
43
|
+
find_by_verification_token!(token).tap do |identity|
|
44
|
+
# ensure 'uid' exists, needed for 'identity' provider
|
45
|
+
identity.uid = identity.id if identity.uid.blank?
|
46
|
+
identity.verification_token = nil
|
47
|
+
identity.verified_at = Time.zone.now
|
48
|
+
identity.save
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Public: Shim to overcome odd behavior seen during testing with SQLite
|
53
|
+
def uid
|
54
|
+
read_attribute :uid
|
55
|
+
end
|
56
|
+
|
57
|
+
# Public: Indicate if the `Identity` has been verified.
|
58
|
+
#
|
59
|
+
# Returns: Boolean.
|
60
|
+
def verified?
|
61
|
+
verification_token.blank? && verified_at.present?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Public: Apply attributes returned from OmniAuth.
|
65
|
+
#
|
66
|
+
# omniauth - An instance of `OmniAuth::AuthHash`.
|
67
|
+
def apply_omniauth(omniauth)
|
68
|
+
info = omniauth["info"]
|
69
|
+
|
70
|
+
user_name = %Q(#{info["first_name"]} #{info["last_name"]})
|
71
|
+
user_name.gsub!(/\s+/, " ").strip!
|
72
|
+
|
73
|
+
self.provider = omniauth["provider"]
|
74
|
+
self.uid = omniauth["uid"]
|
75
|
+
self.name = user_name if self.name.blank?
|
76
|
+
self.email = info["email"] if info["email"] && self.email.blank?
|
77
|
+
self
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Thincloud::Authentication</title>
|
5
|
+
<%= stylesheet_link_tag "thincloud/authentication/application", :media => "all" %>
|
6
|
+
<%= javascript_include_tag "thincloud/authentication/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,69 @@
|
|
1
|
+
<%= form_for @identity, url: registrations_path, html: { class: "form-horizontal" } do |f| %>
|
2
|
+
<fieldset>
|
3
|
+
<legend>Register</legend>
|
4
|
+
|
5
|
+
<% if @identity.errors.any? %>
|
6
|
+
<div class="alert alert-block alert-error">
|
7
|
+
<h4><i class="icon-warning-sign"></i> Error</h4>
|
8
|
+
Please check the following <%= pluralize @identity.errors.size, "item" %>:
|
9
|
+
</div>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<div class="control-group <%= form_error_class_for(f, :name) %>">
|
13
|
+
<%= f.label :name, "Name", class: "control-label" %>
|
14
|
+
<div class="controls">
|
15
|
+
<div class="input-prepend">
|
16
|
+
<span class="add-on"><i class="icon-user"></i></span>
|
17
|
+
<%= f.text_field :name %>
|
18
|
+
</div>
|
19
|
+
<%= content_tag :span, "#{:name.to_s.humanize} #{f.object.errors[:name].to_sentence}", class: "help-inline" %>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
|
24
|
+
<div class="control-group <%= form_error_class_for(f, :email) %>">
|
25
|
+
<%= f.label :email, "Email", class: "control-label" %>
|
26
|
+
<div class="controls">
|
27
|
+
<div class="input-prepend">
|
28
|
+
<span class="add-on"><i class="icon-envelope"></i></span>
|
29
|
+
<%= f.email_field :email %>
|
30
|
+
</div>
|
31
|
+
<%= content_tag :span, "#{:email.to_s.humanize} #{f.object.errors[:email].to_sentence}", class: "help-inline" %>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="control-group <%= form_error_class_for(f, :password_digest) %>">
|
36
|
+
<%= f.label :password, "Password", class: "control-label" %>
|
37
|
+
<div class="controls">
|
38
|
+
<div class="input-prepend">
|
39
|
+
<span class="add-on"><i class="icon-lock"></i></span>
|
40
|
+
<%= f.password_field :password %>
|
41
|
+
</div>
|
42
|
+
<%= content_tag :span, "#{:password.to_s.humanize} #{f.object.errors[:password_digest].to_sentence}", class: "help-inline" %>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div class="control-group <%= form_error_class_for(f, :password) %>">
|
47
|
+
<%= f.label :password_confirmation, "Confirmation", class: "control-label" %>
|
48
|
+
<div class="controls">
|
49
|
+
<div class="input-prepend">
|
50
|
+
<span class="add-on"><i class="icon-lock"></i></span>
|
51
|
+
<%= f.password_field :password_confirmation %>
|
52
|
+
</div>
|
53
|
+
<%= content_tag :span, "#{:password.to_s.humanize} #{f.object.errors[:password].to_sentence}", class: "help-inline" %>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<div class="control-group">
|
58
|
+
<div class="controls">
|
59
|
+
<%= button_tag type: "submit", class: "btn btn-large btn-primary" do %>
|
60
|
+
<i class="icon-ok icon-white"></i> Register
|
61
|
+
<% end %>
|
62
|
+
|
63
|
+
<%= link_to root_url, class: "btn btn-large" do %>
|
64
|
+
<i class="icon-remove"></i> Cancel
|
65
|
+
<% end %>
|
66
|
+
</div>
|
67
|
+
</div>
|
68
|
+
</fieldset>
|
69
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render "registration_form" %>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<%= form_tag auth_callback_url(provider: "identity"), class: "form-horizontal" do %>
|
2
|
+
<fieldset>
|
3
|
+
<legend>Login</legend>
|
4
|
+
|
5
|
+
<% if params[:message].present? %>
|
6
|
+
<div class="alert alert-block alert-error">
|
7
|
+
<h4><i class="icon-warning-sign"></i> Error</h4>
|
8
|
+
<%= params[:message].humanize %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<div class="control-group">
|
13
|
+
<%= label_tag :auth_key, "Email", class: "control-label" %>
|
14
|
+
<div class="controls">
|
15
|
+
<div class="input-prepend">
|
16
|
+
<span class="add-on"><i class="icon-envelope"></i></span>
|
17
|
+
<%= email_field_tag :auth_key, params[:auth_key] %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class="control-group">
|
23
|
+
<%= label_tag :password, "Password", class: "control-label" %>
|
24
|
+
<div class="controls">
|
25
|
+
<div class="input-prepend">
|
26
|
+
<span class="add-on"><i class="icon-lock"></i></span>
|
27
|
+
<%= password_field_tag :password %>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<div class="control-group">
|
33
|
+
<div class="controls">
|
34
|
+
<%= button_tag type: "submit", class: "btn btn-large btn-primary" do %>
|
35
|
+
<i class="icon-ok icon-white"></i> Login
|
36
|
+
<% end %>
|
37
|
+
|
38
|
+
or
|
39
|
+
|
40
|
+
<%= link_to signup_url, class: "btn btn-large" do %>
|
41
|
+
<i class="icon-user"></i> Signup
|
42
|
+
<% end %>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
</fieldset>
|
46
|
+
<% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<div class="tabbable">
|
2
|
+
<ul class="nav nav-tabs">
|
3
|
+
<li class="active">
|
4
|
+
<a href="#login" data-toggle="tab"><i class="icon-lock"></i> Login</a>
|
5
|
+
</li>
|
6
|
+
<li>
|
7
|
+
<a href="#register" data-toggle="tab"><i class="icon-user"></i> Register</a>
|
8
|
+
</li>
|
9
|
+
</ul>
|
10
|
+
|
11
|
+
<div class="tab-content">
|
12
|
+
<!-- Login -->
|
13
|
+
<div class="tab-pane active" id="login">
|
14
|
+
<%= render "login_form" %>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<!-- Register -->
|
18
|
+
<div class="tab-pane" id="register">
|
19
|
+
<%= render "thincloud/authentication/registrations/registration_form" %>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Thincloud::Authentication::Engine.routes.draw do
|
2
|
+
match ":provider/callback" => "registrations#create", as: "auth_callback"
|
3
|
+
get "failure", to: "sessions#new", as: "auth_failure"
|
4
|
+
|
5
|
+
get "login", to: "sessions#new", as: "login"
|
6
|
+
delete "logout", to: "sessions#destroy", as: "logout"
|
7
|
+
get "authenticated", to: "sessions#authenticated"
|
8
|
+
|
9
|
+
resources :registrations, only: [:new, :create]
|
10
|
+
get "signup", to: "registrations#new", as: "signup"
|
11
|
+
get "verify/:token", to: "registrations#verify", as: "verify_token"
|
12
|
+
|
13
|
+
root to: "sessions#new"
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateThincloudAuthenticationIdentities < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :thincloud_authentication_identities do |t|
|
4
|
+
t.integer :user_id, null: false
|
5
|
+
t.string :provider, null: false, default: "identity"
|
6
|
+
t.string :uid
|
7
|
+
t.string :name, null: false
|
8
|
+
t.string :email, null: false
|
9
|
+
t.string :password_digest, null: false
|
10
|
+
t.string :verification_token
|
11
|
+
t.datetime :verified_at
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
add_index :thincloud_authentication_identities, :user_id
|
16
|
+
add_index :thincloud_authentication_identities, [:provider, :uid], unique: true
|
17
|
+
add_index :thincloud_authentication_identities, :email
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require "thincloud/authentication/configuration"
|
2
|
+
require "thincloud/authentication/engine"
|
3
|
+
require "thincloud/authentication/authenticatable_controller"
|
4
|
+
require "thincloud/authentication/identifiable_user"
|
5
|
+
|
6
|
+
module Thincloud
|
7
|
+
module Authentication
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Thincloud
|
2
|
+
module Authentication
|
3
|
+
|
4
|
+
module AuthenticatableController
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
helper_method :current_user
|
9
|
+
helper_method :logged_in?
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
# Protected: The user that is currently logged in.
|
15
|
+
#
|
16
|
+
# This method is also available as a view helper.
|
17
|
+
#
|
18
|
+
# Returns: An instance of `User` or `nil`.
|
19
|
+
def current_user
|
20
|
+
return nil if session[:uid].blank?
|
21
|
+
@current_user ||= User.find(session[:uid])
|
22
|
+
end
|
23
|
+
|
24
|
+
# Protected: Determine if the current request has a logged in user.
|
25
|
+
#
|
26
|
+
# This method is also available as a view helper.
|
27
|
+
#
|
28
|
+
# Returns: Boolean.
|
29
|
+
def logged_in?
|
30
|
+
current_user.present?
|
31
|
+
end
|
32
|
+
|
33
|
+
# Protected: Require an authenticated user to perform an action.
|
34
|
+
#
|
35
|
+
# Use in a `before_filter`.
|
36
|
+
#
|
37
|
+
# Returns: Redirect if not logged in, otherwise `nil`.
|
38
|
+
def authenticate!
|
39
|
+
unless logged_in?
|
40
|
+
redirect_to login_url, alert: "You must be logged in to continue."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Protected: Set the `current_user` to the provided `User` instance.
|
45
|
+
#
|
46
|
+
# user - An instance of `User` that has been authenticated.
|
47
|
+
#
|
48
|
+
# Returns: The `id` of the provided user.
|
49
|
+
def login_as(user)
|
50
|
+
reset_session # avoid session fixation
|
51
|
+
session[:uid] = user.id
|
52
|
+
end
|
53
|
+
|
54
|
+
# Protected: Clear the session of an authenticated user.
|
55
|
+
#
|
56
|
+
# Returns: A new empty session instance.
|
57
|
+
def logout
|
58
|
+
reset_session
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Thincloud::Authentication
|
2
|
+
class << self
|
3
|
+
attr_accessor :configuration
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.configure
|
7
|
+
self.configuration ||= Configuration.new
|
8
|
+
yield configuration
|
9
|
+
end
|
10
|
+
|
11
|
+
# Public: Configuration options for the Thincloud::Authentication module
|
12
|
+
class Configuration
|
13
|
+
attr_accessor :providers, :mailer_sender
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@providers = {}
|
17
|
+
@mailer_sender = "app@example.com"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Thincloud
|
2
|
+
module Authentication
|
3
|
+
# Public: Initialize the Rails engine
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
isolate_namespace Thincloud::Authentication
|
6
|
+
|
7
|
+
initializer "thincloud.authentication.omniauth.middleware" do |app|
|
8
|
+
require "omniauth"
|
9
|
+
require "omniauth-identity"
|
10
|
+
|
11
|
+
config = Thincloud::Authentication.configuration || Configuration.new
|
12
|
+
strategies = config.providers.keys
|
13
|
+
strategies.each { |strategy| require "omniauth-#{strategy}" }
|
14
|
+
|
15
|
+
app.middleware.use ::OmniAuth::Builder do
|
16
|
+
|
17
|
+
# always provide the Identity strategy
|
18
|
+
provider :identity, fields: [:email], model: Identity,
|
19
|
+
on_failed_registration: RegistrationsController.action(:new)
|
20
|
+
|
21
|
+
strategies.each do |strategy|
|
22
|
+
provider strategy, ENV["#{strategy.to_s.upcase}_CONSUMER_KEY"],
|
23
|
+
ENV["#{strategy.to_s.upcase}_CONSUMER_SECRET"],
|
24
|
+
fields: config.providers[strategy][:fields],
|
25
|
+
scope: config.providers[strategy][:scopes]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
initializer "thincloud.authentication.omniauth.logger" do
|
31
|
+
::OmniAuth.config.logger = ::Rails.logger
|
32
|
+
end
|
33
|
+
|
34
|
+
initializer "thincloud.authentication.omniauth.failure_endpoint" do
|
35
|
+
::OmniAuth.config.on_failure = -> env do
|
36
|
+
::OmniAuth::FailureEndpoint.new(env).redirect_to_failure
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
initializer "thincloud.authentication.omniauth.identity_redirects" do
|
41
|
+
# override default omniauth-identity forms
|
42
|
+
class ::OmniAuth::Strategies::Identity
|
43
|
+
def registration_form
|
44
|
+
redirect "/signup"
|
45
|
+
end
|
46
|
+
|
47
|
+
def request_phase
|
48
|
+
redirect "/login"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
initializer "thincloud.authentication.user" do
|
54
|
+
::User.send :include, Thincloud::Authentication::IdentifiableUser
|
55
|
+
end
|
56
|
+
|
57
|
+
initializer "thincloud.authentication.action_controller" do
|
58
|
+
ActionController::Base.send :include,
|
59
|
+
Thincloud::Authentication::AuthenticatableController
|
60
|
+
end
|
61
|
+
|
62
|
+
config.generators do |g|
|
63
|
+
g.test_framework :mini_test, spec: true, fixture: false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,287 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: thincloud-authentication
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Phil Cohen
|
9
|
+
- Robert Bousquet
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-09-23 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.2.8
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 3.2.8
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: omniauth
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 1.1.1
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.1.1
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: omniauth-identity
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.1.0
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.1.0
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: omniauth-linkedin
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 0.0.8
|
71
|
+
type: :runtime
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 0.0.8
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: cane
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ~>
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 2.3.0
|
87
|
+
type: :development
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ~>
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 2.3.0
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: guard
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ~>
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 1.3.3
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.3.3
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: minitest
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ~>
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 3.4.0
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ~>
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: 3.4.0
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: guard-minitest
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ~>
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: 0.5.0
|
135
|
+
type: :development
|
136
|
+
prerelease: false
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ~>
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 0.5.0
|
143
|
+
- !ruby/object:Gem::Dependency
|
144
|
+
name: minitest-rails
|
145
|
+
requirement: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ~>
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 0.1.3
|
151
|
+
type: :development
|
152
|
+
prerelease: false
|
153
|
+
version_requirements: !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
155
|
+
requirements:
|
156
|
+
- - ~>
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: 0.1.3
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: minitest-rails-shoulda
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
none: false
|
163
|
+
requirements:
|
164
|
+
- - ~>
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.1.0
|
167
|
+
type: :development
|
168
|
+
prerelease: false
|
169
|
+
version_requirements: !ruby/object:Gem::Requirement
|
170
|
+
none: false
|
171
|
+
requirements:
|
172
|
+
- - ~>
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 0.1.0
|
175
|
+
- !ruby/object:Gem::Dependency
|
176
|
+
name: rb-fsevent
|
177
|
+
requirement: !ruby/object:Gem::Requirement
|
178
|
+
none: false
|
179
|
+
requirements:
|
180
|
+
- - ~>
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: 0.9.1
|
183
|
+
type: :development
|
184
|
+
prerelease: false
|
185
|
+
version_requirements: !ruby/object:Gem::Requirement
|
186
|
+
none: false
|
187
|
+
requirements:
|
188
|
+
- - ~>
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: 0.9.1
|
191
|
+
- !ruby/object:Gem::Dependency
|
192
|
+
name: simplecov
|
193
|
+
requirement: !ruby/object:Gem::Requirement
|
194
|
+
none: false
|
195
|
+
requirements:
|
196
|
+
- - ~>
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
version: 0.6.4
|
199
|
+
type: :development
|
200
|
+
prerelease: false
|
201
|
+
version_requirements: !ruby/object:Gem::Requirement
|
202
|
+
none: false
|
203
|
+
requirements:
|
204
|
+
- - ~>
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: 0.6.4
|
207
|
+
- !ruby/object:Gem::Dependency
|
208
|
+
name: mocha
|
209
|
+
requirement: !ruby/object:Gem::Requirement
|
210
|
+
none: false
|
211
|
+
requirements:
|
212
|
+
- - ~>
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: 0.12.4
|
215
|
+
type: :development
|
216
|
+
prerelease: false
|
217
|
+
version_requirements: !ruby/object:Gem::Requirement
|
218
|
+
none: false
|
219
|
+
requirements:
|
220
|
+
- - ~>
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 0.12.4
|
223
|
+
description: Rails Engine to provide authentication for Thincloud applications
|
224
|
+
email:
|
225
|
+
- pcohen@newleaders.com
|
226
|
+
- rbousquet@newleaders.com
|
227
|
+
executables: []
|
228
|
+
extensions: []
|
229
|
+
extra_rdoc_files: []
|
230
|
+
files:
|
231
|
+
- app/assets/javascripts/thincloud/authentication/application.js
|
232
|
+
- app/assets/stylesheets/thincloud/authentication/application.css
|
233
|
+
- app/controllers/thincloud/authentication/application_controller.rb
|
234
|
+
- app/controllers/thincloud/authentication/registrations_controller.rb
|
235
|
+
- app/controllers/thincloud/authentication/sessions_controller.rb
|
236
|
+
- app/helpers/thincloud/authentication/registrations_helper.rb
|
237
|
+
- app/mailers/thincloud/authentication/registrations_mailer.rb
|
238
|
+
- app/models/thincloud/authentication/identity.rb
|
239
|
+
- app/views/thincloud/authentication/layouts/application.html.erb
|
240
|
+
- app/views/thincloud/authentication/registrations/_registration_form.html.erb
|
241
|
+
- app/views/thincloud/authentication/registrations/new.html.erb
|
242
|
+
- app/views/thincloud/authentication/registrations_mailer/verification_token.text.erb
|
243
|
+
- app/views/thincloud/authentication/sessions/_login_form.html.erb
|
244
|
+
- app/views/thincloud/authentication/sessions/new.html.erb
|
245
|
+
- config/routes.rb
|
246
|
+
- db/migrate/20120918233329_create_thincloud_authentication_identities.rb
|
247
|
+
- lib/tasks/thincloud-authentication_tasks.rake
|
248
|
+
- lib/thincloud/authentication/authenticatable_controller.rb
|
249
|
+
- lib/thincloud/authentication/configuration.rb
|
250
|
+
- lib/thincloud/authentication/engine.rb
|
251
|
+
- lib/thincloud/authentication/identifiable_user.rb
|
252
|
+
- lib/thincloud/authentication/version.rb
|
253
|
+
- lib/thincloud-authentication.rb
|
254
|
+
- MIT-LICENSE
|
255
|
+
- Rakefile
|
256
|
+
- README.md
|
257
|
+
homepage: https://github.com/newleaders/thincloud-authentication
|
258
|
+
licenses: []
|
259
|
+
post_install_message:
|
260
|
+
rdoc_options: []
|
261
|
+
require_paths:
|
262
|
+
- lib
|
263
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
264
|
+
none: false
|
265
|
+
requirements:
|
266
|
+
- - ! '>='
|
267
|
+
- !ruby/object:Gem::Version
|
268
|
+
version: '0'
|
269
|
+
segments:
|
270
|
+
- 0
|
271
|
+
hash: 3364386958863775653
|
272
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
273
|
+
none: false
|
274
|
+
requirements:
|
275
|
+
- - ! '>='
|
276
|
+
- !ruby/object:Gem::Version
|
277
|
+
version: '0'
|
278
|
+
segments:
|
279
|
+
- 0
|
280
|
+
hash: 3364386958863775653
|
281
|
+
requirements: []
|
282
|
+
rubyforge_project:
|
283
|
+
rubygems_version: 1.8.24
|
284
|
+
signing_key:
|
285
|
+
specification_version: 3
|
286
|
+
summary: Rails Engine to provide authentication for Thincloud applications
|
287
|
+
test_files: []
|