thincloud-authentication 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/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
|
+
[](http://travis-ci.org/newleaders/thincloud-authentication) [](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: []
|