ninsho 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +152 -0
- data/Rakefile +1 -0
- data/app/controllers/ninsho/sessions_controller.rb +23 -0
- data/app/controllers/ninsho_controller.rb +45 -0
- data/app/helpers/ninsho_helper.rb +74 -0
- data/app/views/ninsho/sessions/new.html.erb +3 -0
- data/config/locales/en.yml +5 -0
- data/lib/generators/active_record/ninsho_generator.rb +51 -0
- data/lib/generators/active_record/templates/existing_migration.rb +22 -0
- data/lib/generators/active_record/templates/migration.rb +14 -0
- data/lib/generators/ninsho/install_generator.rb +20 -0
- data/lib/generators/ninsho/ninsho_generator.rb +23 -0
- data/lib/generators/ninsho/orm_helpers.rb +22 -0
- data/lib/generators/ninsho/views_generator.rb +50 -0
- data/lib/generators/templates/README +10 -0
- data/lib/generators/templates/ninsho.rb +12 -0
- data/lib/ninsho/authentication.rb +38 -0
- data/lib/ninsho/controllers/helpers.rb +79 -0
- data/lib/ninsho/interface.rb +29 -0
- data/lib/ninsho/omniauth/config.rb +44 -0
- data/lib/ninsho/omniauth.rb +17 -0
- data/lib/ninsho/orm/active_record.rb +1 -0
- data/lib/ninsho/rails/routes.rb +41 -0
- data/lib/ninsho/rails.rb +22 -0
- data/lib/ninsho/railtie.rb +7 -0
- data/lib/ninsho/routes_drawer.rb +20 -0
- data/lib/ninsho/version.rb +3 -0
- data/lib/ninsho.rb +68 -0
- data/ninsho.gemspec +26 -0
- metadata +125 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Abraham Kuri Vargas
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
#Ninsho
|
2
|
+
|
3
|
+
Ninsho is easy flexible authentication solution when using providers
|
4
|
+
|
5
|
+
* Is a complete MVC solution based on Rails Engines;
|
6
|
+
* Works with most providers out there, Github, Facebook, Twitter, Linkedin
|
7
|
+
|
8
|
+
|
9
|
+
## Getting started
|
10
|
+
|
11
|
+
Ninsho 0.0.1 works with rails 3.1 onwards. You can add it to your Gemfile with:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'ninsho'
|
15
|
+
```
|
16
|
+
|
17
|
+
Then run the bundle command to install it.
|
18
|
+
|
19
|
+
After you install Ninsho and add it to your Gemfile, you need to run the generator:
|
20
|
+
|
21
|
+
```console
|
22
|
+
rails g ninsho:install
|
23
|
+
```
|
24
|
+
|
25
|
+
The generator will install in initializer which describes all the Ninsho's configuration options, so we recommend you take a look at it. When you are done you are ready to start the ninsho process, first you need to generate an authentications model or so:
|
26
|
+
|
27
|
+
```console
|
28
|
+
rails g ninsho MODEL
|
29
|
+
```
|
30
|
+
|
31
|
+
Before yout start generating, we are assuming you have a model to relate to, in most cases a 'User' class, just for you to be aware and that it has an email attribute.
|
32
|
+
|
33
|
+
Replace MODEL by the class name used for the app authentications, it is commonly 'Authentication'. This will create a model(if one does not exists), and add the belongs_to_ninsho method (it's commented don't worry).
|
34
|
+
|
35
|
+
Next you'll probably want to run the migrations "rake db:migrate", as the generator will create a migration file (open it modify if you need). This generator also configures your config/routes.rb file to point to the Ninsho Controller.
|
36
|
+
|
37
|
+
### Stop right here!
|
38
|
+
|
39
|
+
Once you have the 'User' model and the 'Authentication' model, you just have to relate them:
|
40
|
+
|
41
|
+
\> app/models/user.rb
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
has_many :authentications
|
45
|
+
```
|
46
|
+
|
47
|
+
\> app/models/authentication.rb
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
belongs_to_ninsho :user
|
51
|
+
```
|
52
|
+
|
53
|
+
### Controller and helpers
|
54
|
+
|
55
|
+
Ninsho will create some helpers to use inside your controllers and views.
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
before_filter :authenticate_user!
|
59
|
+
```
|
60
|
+
|
61
|
+
To check if the user is signed in
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
user_signed_in?
|
65
|
+
```
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
current_user
|
69
|
+
```
|
70
|
+
|
71
|
+
After user is signed in or signed out it will be redirected to the root_path, but you can always change this by overwriting the `redirect_on_sign_in_path` or `redirect_on_sign_out_path`
|
72
|
+
|
73
|
+
Notice if you relate the ninsho model with for example a member model, then the helpers you should use are:
|
74
|
+
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
before_filter :authenticate_member!
|
78
|
+
```
|
79
|
+
|
80
|
+
To check if the user is signed in
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
member_signed_in?
|
84
|
+
```
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
current_member
|
88
|
+
```
|
89
|
+
|
90
|
+
### Configuring views
|
91
|
+
|
92
|
+
Since Ninsho is a Rails Engine it provides a simple view for handling the session, it is very basic so you might want to change them. In this case you can run the generator and it will copy all views to your app:
|
93
|
+
|
94
|
+
```console
|
95
|
+
rails g ninsho:views
|
96
|
+
```
|
97
|
+
|
98
|
+
### Omniauth
|
99
|
+
|
100
|
+
Ninsho plays good with many providers (some test would not hurt), such as github, facebook, twitter, linkedin, and to configure them you just need to add the omniauth-provider gem to your Gemfile like so:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
gem 'omniauth-facebook'
|
104
|
+
```
|
105
|
+
|
106
|
+
And after that if you want ninsho to respond to that, you just need to add the provider in `config/initializers/ninsho.rb`:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
config.omniauth :facebook, "APP_ID", "APP_SECRET", :scope => 'email'
|
110
|
+
```
|
111
|
+
|
112
|
+
### I18n
|
113
|
+
|
114
|
+
You can overwrite the ninsho locale and customize the flash messages:
|
115
|
+
|
116
|
+
```yaml
|
117
|
+
en:
|
118
|
+
ninsho:
|
119
|
+
sessions:
|
120
|
+
signed_in: "Signed in successfully"
|
121
|
+
signed_out: "Signed out successfully"
|
122
|
+
```
|
123
|
+
|
124
|
+
### Changelog
|
125
|
+
|
126
|
+
* Current gem version 0.0.1
|
127
|
+
|
128
|
+
### Devs
|
129
|
+
|
130
|
+
* Abraham Kuri (https://github.com/kurenn)
|
131
|
+
|
132
|
+
### Future
|
133
|
+
|
134
|
+
* Add more flexibility to handle authentications and save multiple to fields
|
135
|
+
* Add tests
|
136
|
+
* Support for Mongoid
|
137
|
+
* Add handy helpers
|
138
|
+
* Add aouth token for Facebook friends
|
139
|
+
* Add more documentation on code
|
140
|
+
|
141
|
+
## Credits
|
142
|
+
Icalia Labs - weare@icalialabs.com
|
143
|
+
|
144
|
+
[Follow us](http://twitter.com/icalialabs "Follow us")
|
145
|
+
|
146
|
+
|
147
|
+
[Like us on Facebook](https://www.facebook.com/icalialab "Like us on Facebook")
|
148
|
+
|
149
|
+
|
150
|
+
### License
|
151
|
+
|
152
|
+
MIT License. Copyright 2012-2013 IcaliaLabs. http://icalialabs.com
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Ninsho::SessionsController < NinshoController
|
2
|
+
|
3
|
+
def new
|
4
|
+
@providers = Ninsho.providers
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
resource = build_resource_from_omniauth
|
9
|
+
if resource.authenticated?
|
10
|
+
sign_in resource.send(Ninsho.parent_resource_name.to_s.downcase).id
|
11
|
+
flash_message(:notice, :signed_in)
|
12
|
+
redirect_on_sign_in_path
|
13
|
+
else
|
14
|
+
redirect_to_root
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
sign_out
|
20
|
+
flash_message(:notice, :signed_out)
|
21
|
+
redirect_on_sign_out_path
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class NinshoController < Ninsho.parent_controller.constantize
|
2
|
+
|
3
|
+
helpers = %w(resource resource_name resource_class resource_params)
|
4
|
+
hide_action *helpers
|
5
|
+
helper_method *helpers
|
6
|
+
|
7
|
+
def flash_message(key, action)
|
8
|
+
message = I18n.t("ninsho.sessions.#{action}")
|
9
|
+
flash[key] = message if message.present?
|
10
|
+
end
|
11
|
+
|
12
|
+
# Gets the actual resource stored in the instance variable
|
13
|
+
def resource
|
14
|
+
instance_variable_get(:"@#{resource_name}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource_params
|
18
|
+
env['omniauth.auth']
|
19
|
+
end
|
20
|
+
|
21
|
+
# Proxy to ninsho map name
|
22
|
+
def resource_name
|
23
|
+
Ninsho.resource_name #authentication
|
24
|
+
end
|
25
|
+
|
26
|
+
def resource_class
|
27
|
+
Ninsho.resource_class
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sets the resource creating an instance variable
|
31
|
+
def resource=(new_resource)
|
32
|
+
instance_variable_set(:"@#{resource_name}", new_resource)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Parent resource
|
36
|
+
def parent_resource
|
37
|
+
resource_class.reflect_on_all_associations(:belongs_to).first.name.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
# Build a ninsho resource.
|
41
|
+
# Assignment bypasses attribute protection when :unsafe option is passed
|
42
|
+
def build_resource_from_omniauth
|
43
|
+
self.resource = resource_class.from_omniauth(resource_params)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module NinshoHelper
|
2
|
+
|
3
|
+
RESOURCE_NAME = Ninsho.resource_name.singularize
|
4
|
+
PARENT_RESOURCE_NAME = Ninsho.parent_resource_name.to_s.downcase
|
5
|
+
|
6
|
+
def store_location
|
7
|
+
session[:return_to] = request.fullpath
|
8
|
+
end
|
9
|
+
|
10
|
+
def clear_return_to
|
11
|
+
session[:return_to] = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def redirect_back_or(default)
|
15
|
+
redirect_to(session[:return_to] || default )
|
16
|
+
clear_return_to
|
17
|
+
end
|
18
|
+
|
19
|
+
def after_sign_in_path_for
|
20
|
+
redirect_back_or redirect_to_root
|
21
|
+
end
|
22
|
+
|
23
|
+
def sign_out
|
24
|
+
session["#{PARENT_RESOURCE_NAME}_id".to_sym] = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def sign_in_and_redirect(parent_id, path=nil)
|
28
|
+
session["#{PARENT_RESOURCE_NAME}_id".to_sym] = parent_id
|
29
|
+
redirect_to path
|
30
|
+
end
|
31
|
+
|
32
|
+
def sign_in(parent_id)
|
33
|
+
session["#{PARENT_RESOURCE_NAME}_id".to_sym] = parent_id
|
34
|
+
end
|
35
|
+
|
36
|
+
class_eval <<-METHODS, __FILE__, __LINE__ + 1
|
37
|
+
def current_#{PARENT_RESOURCE_NAME}
|
38
|
+
@current_#{PARENT_RESOURCE_NAME} ||= #{Ninsho.parent_resource_name}.find(session[:#{PARENT_RESOURCE_NAME}_id]) if session[:#{PARENT_RESOURCE_NAME}_id]
|
39
|
+
end
|
40
|
+
|
41
|
+
def #{PARENT_RESOURCE_NAME}_signed_in?
|
42
|
+
current_#{PARENT_RESOURCE_NAME}.present?
|
43
|
+
end
|
44
|
+
|
45
|
+
def authenticate_#{PARENT_RESOURCE_NAME}!
|
46
|
+
deny_access unless #{PARENT_RESOURCE_NAME}_signed_in?
|
47
|
+
end
|
48
|
+
|
49
|
+
METHODS
|
50
|
+
|
51
|
+
define_method "link_#{RESOURCE_NAME}_with" do |provider|
|
52
|
+
link_to "Connect with #{provider.to_s.capitalize}", "auth/#{provider.to_s}"
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# Method used by sessions controller to sign out a user.
|
57
|
+
# You can overwrite it in your ApplicationController
|
58
|
+
#
|
59
|
+
# By default it is the root_path.
|
60
|
+
def redirect_on_sign_out_path
|
61
|
+
redirect_to_root
|
62
|
+
end
|
63
|
+
|
64
|
+
def redirect_on_sign_in_path
|
65
|
+
redirect_to_root
|
66
|
+
end
|
67
|
+
def redirect_to_root
|
68
|
+
redirect_to respond_to?(:root_path) ? root_path : "/"
|
69
|
+
end
|
70
|
+
|
71
|
+
def deny_access
|
72
|
+
redirect_to_root
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
require 'generators/ninsho/orm_helpers'
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
module Generators
|
6
|
+
class NinshoGenerator < ActiveRecord::Generators::Base
|
7
|
+
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
8
|
+
|
9
|
+
include Ninsho::Generators::OrmHelpers
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
|
+
|
12
|
+
def copy_ninsho_migration
|
13
|
+
if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
|
14
|
+
migration_template "existing_migration.rb", "db/migrate/add_ninsho_to_#{table_name}"
|
15
|
+
else
|
16
|
+
migration_template "migration.rb", "db/migrate/ninsho_create_#{table_name}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_model
|
21
|
+
invoke "active_record:model", [name], :migration => false unless model_exists? && behavior == :invoke
|
22
|
+
end
|
23
|
+
|
24
|
+
def inject_ninsho_content
|
25
|
+
content = <<CONTENT
|
26
|
+
attr_accessible :provider, :uid
|
27
|
+
# belongs_to_ninsho :user
|
28
|
+
CONTENT
|
29
|
+
|
30
|
+
class_path = if namespaced?
|
31
|
+
class_name.to_s.split("::")
|
32
|
+
else
|
33
|
+
[class_name]
|
34
|
+
end
|
35
|
+
|
36
|
+
indent_depth = class_path.size - 1
|
37
|
+
content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
|
38
|
+
inject_into_class(model_path, class_path.last, content) if model_exists?
|
39
|
+
end
|
40
|
+
|
41
|
+
def migration_data
|
42
|
+
<<RUBY
|
43
|
+
## Database authentications
|
44
|
+
t.integer :user_id
|
45
|
+
t.string :provider
|
46
|
+
t.string :uid
|
47
|
+
RUBY
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class AddNinshoTo<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_table(:<%= table_name %>) do |t|
|
4
|
+
<%= migration_data -%>
|
5
|
+
|
6
|
+
<% attributes.each do |attribute| -%>
|
7
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
8
|
+
<% end -%>
|
9
|
+
|
10
|
+
# Uncomment below if timestamps were not included in your original model.
|
11
|
+
# t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :<%= table_name %>, :user_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
# By default, we don't want to make any assumption about how to roll back a migration when your
|
19
|
+
# model already existed. Please edit below which fields you would like to remove in this migration.
|
20
|
+
raise ActiveRecord::IrreversibleMigration
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class NinshoCreate<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table(:<%= table_name %>) do |t|
|
4
|
+
<%= migration_data -%>
|
5
|
+
|
6
|
+
<% attributes.each do |attribute| -%>
|
7
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
8
|
+
<% end -%>
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
add_index :<%= table_name %>, :user_id
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Ninsho
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path("../../templates", __FILE__)
|
7
|
+
|
8
|
+
desc "Creates a Ninsho initializer to your application."
|
9
|
+
class_option :orm
|
10
|
+
|
11
|
+
def copy_initializer
|
12
|
+
template 'ninsho.rb', "config/initializers/ninsho.rb"
|
13
|
+
end
|
14
|
+
|
15
|
+
def display_readme
|
16
|
+
readme "README" if behavior == :invoke
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ninsho
|
2
|
+
module Generators
|
3
|
+
class NinshoGenerator < Rails::Generators::NamedBase
|
4
|
+
include Rails::Generators::ResourceHelpers
|
5
|
+
|
6
|
+
namespace "ninsho"
|
7
|
+
desc "Creates a model with the given name with ninsho" <<
|
8
|
+
"includes migration files, and routes config"
|
9
|
+
|
10
|
+
hook_for :orm
|
11
|
+
|
12
|
+
class_option :routes, :desc => "Generate routes", :type => :boolean, :default => true
|
13
|
+
|
14
|
+
def add_ninsho_routes
|
15
|
+
ninsho_routes = "ninsho_on :#{plural_name}"
|
16
|
+
ninsho_routes << %Q(, :class_name => "#{class_name}") if class_name.include?("::")
|
17
|
+
ninsho_routes << %Q(, :skip => :all) unless options.routes?
|
18
|
+
route ninsho_routes
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ninsho
|
2
|
+
module Generators
|
3
|
+
module OrmHelpers
|
4
|
+
|
5
|
+
def model_exists?
|
6
|
+
File.exists?(File.join(destination_root, model_path))
|
7
|
+
end
|
8
|
+
|
9
|
+
def migration_exists?(table_name)
|
10
|
+
Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_add_ninsho_to_#{table_name}.rb$/).first
|
11
|
+
end
|
12
|
+
|
13
|
+
def migration_path
|
14
|
+
@migration_path ||= File.join("db", "migrate")
|
15
|
+
end
|
16
|
+
|
17
|
+
def model_path
|
18
|
+
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Ninsho
|
2
|
+
module Generators
|
3
|
+
# Include this module in your generator to generate Ninsho views.
|
4
|
+
# `copy_views` is the main method and by default copies all views
|
5
|
+
# with forms.
|
6
|
+
module ViewPathTemplates #:nodoc:
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
argument :scope, :required => false, :default => nil,
|
11
|
+
:desc => "The scope to copy views to"
|
12
|
+
|
13
|
+
public_task :copy_views
|
14
|
+
end
|
15
|
+
|
16
|
+
def copy_views
|
17
|
+
view_directory :sessions
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def view_directory(name, _target_path = nil)
|
23
|
+
directory name.to_s, _target_path || "#{target_path}/#{name}" do |content|
|
24
|
+
content
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def target_path
|
29
|
+
@target_path ||= "app/views/ninsho"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
class DefaultGenerator < Rails::Generators::Base #:nodoc:
|
35
|
+
include ViewPathTemplates
|
36
|
+
source_root File.expand_path("../../../../app/views/ninsho", __FILE__)
|
37
|
+
desc "Copies default Ninsho views to your application."
|
38
|
+
end
|
39
|
+
|
40
|
+
class ViewsGenerator < Rails::Generators::Base
|
41
|
+
desc "Copies Ninsho views to your application."
|
42
|
+
|
43
|
+
argument :scope, :required => false, :default => nil,
|
44
|
+
:desc => "The scope to copy views to"
|
45
|
+
|
46
|
+
invoke DefaultGenerator
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
===============================================================================
|
2
|
+
|
3
|
+
Hey you, thanks for installing Ninsho, here are some tips:
|
4
|
+
|
5
|
+
1. You can copy Ninsho views (for customization) to your app by running:
|
6
|
+
|
7
|
+
rails g ninsho:views
|
8
|
+
|
9
|
+
===============================================================================
|
10
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# This hook is use to setup the configuration for creating models through
|
2
|
+
# rails generators
|
3
|
+
Ninsho.setup do |config|
|
4
|
+
|
5
|
+
# ==> ORM Configuration
|
6
|
+
# Load and configure the ORM. Supports :active_record
|
7
|
+
require 'ninsho/orm/active_record'
|
8
|
+
|
9
|
+
|
10
|
+
#Omniauth Providers
|
11
|
+
#config.omniauth :facebook, "APP_ID", "APP_SECRET", :scope => 'email'
|
12
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Ninsho
|
2
|
+
class Authentication
|
3
|
+
PARENT_RESOURCE_NAME = Ninsho.parent_resource_name.to_s.downcase
|
4
|
+
|
5
|
+
def initialize(omniauth = nil)
|
6
|
+
@omniauth = omniauth
|
7
|
+
@provider = omniauth['provider']
|
8
|
+
@uid = omniauth['uid']
|
9
|
+
@email = omniauth['info']['email']
|
10
|
+
end
|
11
|
+
|
12
|
+
def authenticated?
|
13
|
+
user.present?
|
14
|
+
end
|
15
|
+
|
16
|
+
def from_oauth
|
17
|
+
Ninsho.resource_class.find_by_provider_and_uid(@provider, @uid)
|
18
|
+
end
|
19
|
+
|
20
|
+
def from_user
|
21
|
+
user = Ninsho.parent_resource_name.send :find_by_email, @email
|
22
|
+
if user
|
23
|
+
user.send("#{Ninsho.resource_name.pluralize}").build(provider: @provider, uid: @uid)
|
24
|
+
user.send(:save)
|
25
|
+
user
|
26
|
+
else
|
27
|
+
user = Ninsho.parent_resource_name.send :new, { email: @email }
|
28
|
+
user.send("#{Ninsho.resource_name.pluralize}").build(provider: @provider, uid: @uid)
|
29
|
+
user.send(:save)
|
30
|
+
user
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def user
|
35
|
+
from_oauth.try(Ninsho.parent_resource_name.to_s.downcase.to_sym) || from_user
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Ninsho
|
2
|
+
module Controllers
|
3
|
+
module Helpers
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
RESOURCE_NAME = Ninsho.resource_name.singularize
|
7
|
+
PARENT_RESOURCE_NAME = Ninsho.parent_resource_name.to_s.downcase
|
8
|
+
|
9
|
+
def store_location
|
10
|
+
session[:return_to] = request.fullpath
|
11
|
+
end
|
12
|
+
|
13
|
+
def clear_return_to
|
14
|
+
session[:return_to] = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def redirect_back_or(default)
|
18
|
+
redirect_to(session[:return_to] || default )
|
19
|
+
clear_return_to
|
20
|
+
end
|
21
|
+
|
22
|
+
def after_sign_in_path_for
|
23
|
+
redirect_back_or redirect_to_root
|
24
|
+
end
|
25
|
+
|
26
|
+
def sign_out
|
27
|
+
session["#{PARENT_RESOURCE_NAME}_id".to_sym] = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def sign_in_and_redirect(parent_id, path=nil)
|
31
|
+
session["#{PARENT_RESOURCE_NAME}_id".to_sym] = parent_id
|
32
|
+
redirect_to path
|
33
|
+
end
|
34
|
+
|
35
|
+
def sign_in(parent_id)
|
36
|
+
session["#{PARENT_RESOURCE_NAME}_id".to_sym] = parent_id
|
37
|
+
end
|
38
|
+
|
39
|
+
class_eval <<-METHODS, __FILE__, __LINE__ + 1
|
40
|
+
def current_#{PARENT_RESOURCE_NAME}
|
41
|
+
@current_#{PARENT_RESOURCE_NAME} ||= #{Ninsho.parent_resource_name}.find(session[:#{PARENT_RESOURCE_NAME}_id]) if session[:#{PARENT_RESOURCE_NAME}_id]
|
42
|
+
end
|
43
|
+
|
44
|
+
def #{PARENT_RESOURCE_NAME}_signed_in?
|
45
|
+
current_#{PARENT_RESOURCE_NAME}.present?
|
46
|
+
end
|
47
|
+
|
48
|
+
def authenticate_#{PARENT_RESOURCE_NAME}!
|
49
|
+
deny_access unless #{PARENT_RESOURCE_NAME}_signed_in?
|
50
|
+
end
|
51
|
+
|
52
|
+
METHODS
|
53
|
+
|
54
|
+
define_method "link_#{RESOURCE_NAME}_with" do |provider|
|
55
|
+
link_to "Connect with #{provider.to_s.capitalize}", "auth/#{provider.to_s}"
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Method used by sessions controller to sign out a user.
|
60
|
+
# You can overwrite it in your ApplicationController
|
61
|
+
#
|
62
|
+
# By default it is the root_path.
|
63
|
+
def redirect_on_sign_out_path
|
64
|
+
redirect_to_root
|
65
|
+
end
|
66
|
+
|
67
|
+
def redirect_on_sign_in_path
|
68
|
+
redirect_to_root
|
69
|
+
end
|
70
|
+
def redirect_to_root
|
71
|
+
redirect_to respond_to?(:root_path) ? root_path : "/"
|
72
|
+
end
|
73
|
+
|
74
|
+
def deny_access
|
75
|
+
redirect_to_root
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'ninsho/authentication'
|
2
|
+
|
3
|
+
module Ninsho
|
4
|
+
module Interface
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
def belongs_to_ninsho(*args)
|
12
|
+
options = args.extract_options!
|
13
|
+
|
14
|
+
associations = args.collect(&:to_s).collect(&:downcase)
|
15
|
+
association_keys = associations.collect { |association| "#{association}_id" }
|
16
|
+
|
17
|
+
#Set the belongs_to association by ActiveRecord
|
18
|
+
associations.each do |associated_model|
|
19
|
+
belongs_to associated_model.to_sym
|
20
|
+
Ninsho.parent_resource_name = Ninsho.ref(associated_model.to_s.classify).get
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def from_omniauth(omniauth = nil)
|
25
|
+
Ninsho::Authentication.new(omniauth)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Ninsho
|
2
|
+
module OmniAuth
|
3
|
+
class StrategyNotFound < NameError
|
4
|
+
def initialize(strategy)
|
5
|
+
@strategy = strategy
|
6
|
+
super("Could not find a strategy with name `#{strategy}'." )
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Config
|
11
|
+
attr_accessor :strategy
|
12
|
+
attr_reader :args, :options, :provider, :strategy_name
|
13
|
+
|
14
|
+
def initialize(provider, args)
|
15
|
+
@provider = provider
|
16
|
+
@args = args
|
17
|
+
@options = @args.last.is_a?(Hash) ? @args.last : {}
|
18
|
+
@strategy = nil
|
19
|
+
@strategy_name = options[:name] || @provider
|
20
|
+
@strategy_class = options.delete(:strategy_class)
|
21
|
+
end
|
22
|
+
|
23
|
+
def strategy_class
|
24
|
+
@strategy_class ||= find_strategy || autoload_strategy
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_strategy
|
28
|
+
::OmniAuth.strategies.find do |strategy_class|
|
29
|
+
strategy_class.to_s =~ /#{::OmniAuth::Utils.camelize(strategy_name)}$/ ||
|
30
|
+
strategy_class.default_options[:name] == strategy_name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def autoload_strategy
|
35
|
+
name = ::OmniAuth::Utils.camelize(provider.to_s)
|
36
|
+
if ::OmniAuth::Strategies.const_defined?(name)
|
37
|
+
::OmniAuth::Strategies.const_get(name)
|
38
|
+
else
|
39
|
+
raise StrategyNotFound, name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require "omniauth"
|
3
|
+
require 'omniauth/version'
|
4
|
+
rescue LoadError
|
5
|
+
warn "Could not load 'omniauth'. Please ensure you have the omniauth gem >= 1.0.0 installed and listed in your Gemfile."
|
6
|
+
raise
|
7
|
+
end
|
8
|
+
|
9
|
+
unless OmniAuth::VERSION =~ /^1\./
|
10
|
+
raise "You are using an old OmniAuth version, please ensure you have 1.0.0.pr2 version or later installed."
|
11
|
+
end
|
12
|
+
|
13
|
+
module Ninsho
|
14
|
+
module OmniAuth
|
15
|
+
autoload :Config, "ninsho/omniauth/config"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'orm_adapter/adapters/active_record'
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module ActionDispatch::Routing
|
3
|
+
|
4
|
+
|
5
|
+
class Mapper
|
6
|
+
#Includes the ninsho_on method for routes. This method is responsible
|
7
|
+
# for creating all the routes needed.
|
8
|
+
#
|
9
|
+
# == Example
|
10
|
+
#
|
11
|
+
# Assuming you have an authentications model on your application,
|
12
|
+
# your routes should look like:
|
13
|
+
#
|
14
|
+
# ninsho_on :authentications
|
15
|
+
#
|
16
|
+
# This method will generate something like:
|
17
|
+
#
|
18
|
+
# Session routes
|
19
|
+
# new_authentication_session_path GET /sign_in { controller: 'ninsho/sessions', action: 'new' }
|
20
|
+
# authentication_session_path POST /authentication/:provider/callback { controller: 'ninsho/sessions', action: 'create' }
|
21
|
+
# destroy_authentication_session_path DELETE /sign_out { controller: 'ninsho/sessions', action: 'destroy' }
|
22
|
+
#
|
23
|
+
|
24
|
+
def ninsho_on(resources_name)
|
25
|
+
drawer = Ninsho::RoutesDrawer.new resources_name
|
26
|
+
Ninsho.resource_class = drawer.to
|
27
|
+
Ninsho.resource_name = drawer.resource
|
28
|
+
ninsho_session(drawer.singular_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def ninsho_session(name) #:nodoc:
|
34
|
+
resource :session, :only => [], :controller => 'ninsho/sessions', :path => "" do
|
35
|
+
get :new, :path => 'sign_in', as: "new_#{name}"
|
36
|
+
match :create, path: "auth/:provider/callback", as: "#{name}"
|
37
|
+
delete :destroy, path: 'sign_out', as: "destroy_#{name}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/ninsho/rails.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'ninsho/rails/routes'
|
2
|
+
|
3
|
+
module Ninsho
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
config.ninsho = Ninsho
|
6
|
+
|
7
|
+
# Force routes to be loaded if we are doing any eager load.
|
8
|
+
config.before_eager_load { |app| app.reload_routes! }
|
9
|
+
|
10
|
+
ActiveSupport.on_load(:action_controller) do
|
11
|
+
include Ninsho::Controllers::Helpers
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer "ninsho.omniauth" do |app|
|
15
|
+
Ninsho.omniauth_configs.each do |provider, config|
|
16
|
+
app.middleware.use config.strategy_class, *config.args do |strategy|
|
17
|
+
config.strategy = strategy
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Ninsho
|
2
|
+
# Responsible for handling ninsho mappings and routes configuration
|
3
|
+
# The required value in ninsho_on is actually not used internally, but it's
|
4
|
+
# inflected to find all other values.
|
5
|
+
#
|
6
|
+
class RoutesDrawer #:nodoc:
|
7
|
+
attr_reader :singular_name, :klass, :resource
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@resource = name.to_s
|
11
|
+
@singular_name = name.to_s.singularize
|
12
|
+
@klass = Ninsho.ref(@singular_name.classify)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Gives the class the mapping points to.
|
16
|
+
def to
|
17
|
+
@klass.get
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/ninsho.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require "ninsho/version"
|
3
|
+
require 'orm_adapter'
|
4
|
+
require 'active_support/core_ext/numeric/time'
|
5
|
+
require 'active_support/dependencies'
|
6
|
+
|
7
|
+
module Ninsho
|
8
|
+
|
9
|
+
autoload :OmniAuth, 'ninsho/omniauth'
|
10
|
+
|
11
|
+
module Controllers
|
12
|
+
autoload :Helpers, 'ninsho/controllers/helpers'
|
13
|
+
end
|
14
|
+
|
15
|
+
mattr_accessor :parent_controller
|
16
|
+
@@parent_controller = "ApplicationController"
|
17
|
+
|
18
|
+
mattr_accessor :resource_class
|
19
|
+
@@resource_class = ""
|
20
|
+
|
21
|
+
mattr_accessor :resource_name
|
22
|
+
@@resource_name = ""
|
23
|
+
|
24
|
+
mattr_reader :providers
|
25
|
+
@@providers = []
|
26
|
+
|
27
|
+
mattr_accessor :parent_resource_name
|
28
|
+
@@parent_resource_name = ''
|
29
|
+
|
30
|
+
|
31
|
+
mattr_reader :omniauth_configs
|
32
|
+
@@omniauth_configs = ActiveSupport::OrderedHash.new
|
33
|
+
|
34
|
+
def self.setup
|
35
|
+
yield self
|
36
|
+
end
|
37
|
+
|
38
|
+
class Getter
|
39
|
+
def initialize name
|
40
|
+
@name = name
|
41
|
+
end
|
42
|
+
|
43
|
+
def get
|
44
|
+
ActiveSupport::Dependencies.constantize(@name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.ref(arg)
|
49
|
+
if defined?(ActiveSupport::Dependencies::ClassCache)
|
50
|
+
ActiveSupport::Dependencies::reference(arg)
|
51
|
+
Getter.new(arg)
|
52
|
+
else
|
53
|
+
ActiveSupport::Dependencies.ref(arg)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.omniauth(provider, *args)
|
58
|
+
config = Ninsho::OmniAuth::Config.new(provider, args)
|
59
|
+
@@providers << config.strategy_name.to_sym
|
60
|
+
@@omniauth_configs[config.strategy_name.to_sym] = config
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
require 'ninsho/routes_drawer'
|
66
|
+
require 'ninsho/rails'
|
67
|
+
require 'ninsho/interface'
|
68
|
+
require 'ninsho/railtie'
|
data/ninsho.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ninsho/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "ninsho"
|
8
|
+
gem.version = Ninsho::VERSION
|
9
|
+
gem.platform = Gem::Platform::RUBY
|
10
|
+
gem.authors = ["Abraham Kuri Vargas"]
|
11
|
+
gem.email = ["abraham.kuri@gmail.com"]
|
12
|
+
gem.description = %q{Easy authentication with many providers}
|
13
|
+
gem.summary = %q{Easy authentication with many providers}
|
14
|
+
gem.homepage = ""
|
15
|
+
|
16
|
+
gem.rubyforge_project = "ninsho"
|
17
|
+
|
18
|
+
gem.files = `git ls-files`.split($/)
|
19
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
20
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
21
|
+
gem.require_paths = ["lib"]
|
22
|
+
|
23
|
+
gem.add_dependency("orm_adapter", "~> 0.1")
|
24
|
+
gem.add_dependency "railties", "~> 3.1"
|
25
|
+
gem.add_dependency "activerecord", ">= 3.0"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ninsho
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Abraham Kuri Vargas
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: orm_adapter
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.1'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.1'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: railties
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '3.1'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.1'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: activerecord
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
description: Easy authentication with many providers
|
63
|
+
email:
|
64
|
+
- abraham.kuri@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- Gemfile
|
71
|
+
- LICENSE.txt
|
72
|
+
- README.md
|
73
|
+
- Rakefile
|
74
|
+
- app/controllers/ninsho/sessions_controller.rb
|
75
|
+
- app/controllers/ninsho_controller.rb
|
76
|
+
- app/helpers/ninsho_helper.rb
|
77
|
+
- app/views/ninsho/sessions/new.html.erb
|
78
|
+
- config/locales/en.yml
|
79
|
+
- lib/generators/active_record/ninsho_generator.rb
|
80
|
+
- lib/generators/active_record/templates/existing_migration.rb
|
81
|
+
- lib/generators/active_record/templates/migration.rb
|
82
|
+
- lib/generators/ninsho/install_generator.rb
|
83
|
+
- lib/generators/ninsho/ninsho_generator.rb
|
84
|
+
- lib/generators/ninsho/orm_helpers.rb
|
85
|
+
- lib/generators/ninsho/views_generator.rb
|
86
|
+
- lib/generators/templates/README
|
87
|
+
- lib/generators/templates/ninsho.rb
|
88
|
+
- lib/ninsho.rb
|
89
|
+
- lib/ninsho/authentication.rb
|
90
|
+
- lib/ninsho/controllers/helpers.rb
|
91
|
+
- lib/ninsho/interface.rb
|
92
|
+
- lib/ninsho/omniauth.rb
|
93
|
+
- lib/ninsho/omniauth/config.rb
|
94
|
+
- lib/ninsho/orm/active_record.rb
|
95
|
+
- lib/ninsho/rails.rb
|
96
|
+
- lib/ninsho/rails/routes.rb
|
97
|
+
- lib/ninsho/railtie.rb
|
98
|
+
- lib/ninsho/routes_drawer.rb
|
99
|
+
- lib/ninsho/version.rb
|
100
|
+
- ninsho.gemspec
|
101
|
+
homepage: ''
|
102
|
+
licenses: []
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project: ninsho
|
121
|
+
rubygems_version: 1.8.24
|
122
|
+
signing_key:
|
123
|
+
specification_version: 3
|
124
|
+
summary: Easy authentication with many providers
|
125
|
+
test_files: []
|