auth_provider 0.0.1
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +42 -0
- data/Rakefile +15 -0
- data/app/assets/config/auth_provider_manifest.js +2 -0
- data/app/assets/javascripts/auth_provider/application.js +13 -0
- data/app/assets/stylesheets/auth_provider/application.css +15 -0
- data/app/controllers/auth_provider/application_controller.rb +24 -0
- data/app/controllers/auth_provider/tokens_controller.rb +101 -0
- data/app/helpers/auth_provider/application_helper.rb +4 -0
- data/app/jobs/auth_provider/application_job.rb +4 -0
- data/app/mailers/auth_provider/application_mailer.rb +6 -0
- data/app/models/auth_provider/application_record.rb +5 -0
- data/app/models/auth_provider/oauth_access_token.rb +61 -0
- data/app/models/auth_provider/oauth_session.rb +22 -0
- data/app/views/layouts/auth_provider/application.html.erb +14 -0
- data/config/initializers/inflections.rb +3 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20161119091649_create_auth_provider_oauth_sessions.rb +20 -0
- data/db/migrate/20161119092930_create_auth_provider_oauth_access_tokens.rb +20 -0
- data/lib/auth_provider.rb +6 -0
- data/lib/auth_provider/config.rb +56 -0
- data/lib/auth_provider/engine.rb +5 -0
- data/lib/auth_provider/resource_owner_from_token.rb +8 -0
- data/lib/auth_provider/version.rb +3 -0
- data/lib/generators/auth_provider/install_generator.rb +35 -0
- data/lib/generators/auth_provider/migration_generator.rb +27 -0
- data/lib/generators/auth_provider/templates/auth_provider.rb +32 -0
- data/lib/generators/auth_provider/templates/create_auth_provider_tables.rb +37 -0
- data/lib/tasks/auth_provider_tasks.rake +4 -0
- metadata +177 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bbc87af223a3f381b065ae9d11f2683114429502
|
4
|
+
data.tar.gz: c0a0acdb4e080f05ac031cd7166068c9138aa68e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b964fe1debbc15858e07ce90879ba1c6a1ff6f110f6f71c072f898ad093ed1a504f8f08e9b46ec0fa4749e9da09c0cdac9ca70beb9bc17cd8a37542508ddf00f
|
7
|
+
data.tar.gz: b2d748dc5578fb00b55193794224a089c6dbd801c53ca3451858cdd26a08475e478631832d51f39e985e73a0b2219f7077f29670022e75c05960fd8a4fc242f4
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 Pokai Chang
|
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,42 @@
|
|
1
|
+
# AuthProvider [](https://travis-ci.org/zetavg/AuthProvider) [](https://coveralls.io/github/zetavg/AuthProvider?branch=master)
|
2
|
+
|
3
|
+
A simple authentication provider for Ruby/Rails app. Designed for mobile clients and is compatible with the OAuth 2.0 specification.
|
4
|
+
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'auth_provider'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
```bash
|
17
|
+
$ bundle
|
18
|
+
```
|
19
|
+
|
20
|
+
Run the installation generator with:
|
21
|
+
|
22
|
+
```bash
|
23
|
+
$ rails generate auth_provider:install
|
24
|
+
```
|
25
|
+
|
26
|
+
This will install the auth_provider initializer into `config/initializers/auth_provider.rb`, mount `AuthProvider::Engine` at `/oauth` in `config/routes.rb` and copy the database migration file.
|
27
|
+
|
28
|
+
At last, don't forget to run:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
$ rake db:migrate
|
32
|
+
```
|
33
|
+
|
34
|
+
|
35
|
+
## Configuration
|
36
|
+
|
37
|
+
All the configurations of auth_provider can be found in `config/initializers/auth_provider.rb`, just check it out!
|
38
|
+
|
39
|
+
|
40
|
+
## License
|
41
|
+
|
42
|
+
[MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
|
8
|
+
load 'rails/tasks/statistics.rake'
|
9
|
+
|
10
|
+
require 'bundler/gem_tasks'
|
11
|
+
|
12
|
+
require 'rspec/core/rake_task'
|
13
|
+
RSpec::Core::RakeTask.new(:test)
|
14
|
+
|
15
|
+
task default: :test
|
@@ -0,0 +1,13 @@
|
|
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 any plugin's vendor/assets/javascripts directory 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
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
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 any plugin's vendor/assets/stylesheets directory 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 bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module AuthProvider
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
after_action :cors_set_access_control_headers
|
4
|
+
|
5
|
+
def cors_preflight_check
|
6
|
+
if request.method_symbol == :options
|
7
|
+
headers['Access-Control-Allow-Origin'] = '*'
|
8
|
+
headers['Access-Control-Allow-Methods'] = 'OPTIONS, GET, POST, PUT, PATCH, DELETE'
|
9
|
+
headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization'
|
10
|
+
headers['Access-Control-Max-Age'] = '1728000'
|
11
|
+
head 200
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def cors_set_access_control_headers
|
18
|
+
headers['Access-Control-Allow-Origin'] = '*'
|
19
|
+
headers['Access-Control-Allow-Methods'] = 'OPTIONS, GET, POST, PUT, PATCH, DELETE'
|
20
|
+
headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization'
|
21
|
+
headers['Access-Control-Max-Age'] = '1728000'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require_dependency "auth_provider/application_controller"
|
2
|
+
|
3
|
+
module AuthProvider
|
4
|
+
class TokensController < ApplicationController
|
5
|
+
def create
|
6
|
+
case grant_type
|
7
|
+
when "password"
|
8
|
+
if resource_owner.blank?
|
9
|
+
render(status: 400, json: {
|
10
|
+
error: "invalid_grant",
|
11
|
+
error_description: "Invalid username or password."
|
12
|
+
}) and return
|
13
|
+
end
|
14
|
+
|
15
|
+
oauth_session = OAuthSession.create!(
|
16
|
+
resource_owner: resource_owner,
|
17
|
+
device_type: device_type,
|
18
|
+
device_identifier: device_identifier,
|
19
|
+
device_name: device_name
|
20
|
+
)
|
21
|
+
|
22
|
+
oauth_access_token = oauth_session.oauth_access_tokens.create!
|
23
|
+
|
24
|
+
render(status: 200, json: {
|
25
|
+
access_token: oauth_access_token.token,
|
26
|
+
token_type: "bearer",
|
27
|
+
created_at: oauth_access_token.created_at.to_i,
|
28
|
+
expires_in: oauth_access_token.expires_in,
|
29
|
+
refresh_token: oauth_access_token.refresh_token
|
30
|
+
}) and return
|
31
|
+
|
32
|
+
when "refresh_token"
|
33
|
+
old_oauth_access_token = OAuthAccessToken.not_revoked.find_by(refresh_token: refresh_token)
|
34
|
+
|
35
|
+
if old_oauth_access_token.blank?
|
36
|
+
render(status: 400, json: {
|
37
|
+
error: "invalid_grant",
|
38
|
+
error_description: "The refresh token is invalid."
|
39
|
+
}) and return
|
40
|
+
end
|
41
|
+
|
42
|
+
oauth_access_token = old_oauth_access_token.oauth_session.oauth_access_tokens.create!
|
43
|
+
|
44
|
+
render(status: 200, json: {
|
45
|
+
access_token: oauth_access_token.token,
|
46
|
+
token_type: "bearer",
|
47
|
+
created_at: oauth_access_token.created_at.to_i,
|
48
|
+
expires_in: oauth_access_token.expires_in,
|
49
|
+
refresh_token: oauth_access_token.refresh_token
|
50
|
+
}) and return
|
51
|
+
|
52
|
+
else
|
53
|
+
render(status: 400, json: {
|
54
|
+
error: "unsupported_grant_type",
|
55
|
+
error_description: "Unknown grant type: #{params[:grant_type].presence || 'null'}."
|
56
|
+
}) and return
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def grant_type
|
63
|
+
@grant_type = params[:grant_type]
|
64
|
+
end
|
65
|
+
|
66
|
+
def resource_owner_type
|
67
|
+
@resource_owner_type = params[:resource_owner_type] ||
|
68
|
+
AuthProvider.configuration.default_resource_owner_type
|
69
|
+
end
|
70
|
+
|
71
|
+
def username
|
72
|
+
@username ||= params[:username]
|
73
|
+
end
|
74
|
+
|
75
|
+
def password
|
76
|
+
@password ||= params[:password]
|
77
|
+
end
|
78
|
+
|
79
|
+
def resource_owner
|
80
|
+
@resource_owner ||= AuthProvider.configuration.resource_owner_from_credentials.call(
|
81
|
+
resource_owner_type, username, password
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def device_type
|
86
|
+
@device_type ||= params[:device_type]
|
87
|
+
end
|
88
|
+
|
89
|
+
def device_identifier
|
90
|
+
@device_identifier ||= params[:device_identifier]
|
91
|
+
end
|
92
|
+
|
93
|
+
def device_name
|
94
|
+
@device_name ||= params[:device_name]
|
95
|
+
end
|
96
|
+
|
97
|
+
def refresh_token
|
98
|
+
@refresh_token ||= params[:refresh_token]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module AuthProvider
|
2
|
+
class OAuthAccessToken < ApplicationRecord
|
3
|
+
self.table_name = :oauth_access_tokens
|
4
|
+
|
5
|
+
scope :not_revoked, -> { where(revoked_at: nil) }
|
6
|
+
|
7
|
+
belongs_to :oauth_session, required: true
|
8
|
+
|
9
|
+
delegate :resource_owner, :device_name, :device_type, :device_identifier,
|
10
|
+
to: :oauth_session, prefix: false
|
11
|
+
|
12
|
+
after_initialize :init_token
|
13
|
+
after_initialize :init_refresh_token
|
14
|
+
after_initialize :init_expires_in
|
15
|
+
|
16
|
+
def available?
|
17
|
+
!revoked? && !expired?
|
18
|
+
end
|
19
|
+
|
20
|
+
def expired?
|
21
|
+
Time.now > (created_at || Time.now) + expires_in.seconds
|
22
|
+
end
|
23
|
+
|
24
|
+
def revoked?
|
25
|
+
revoked_at.present? || oauth_session.revoked?
|
26
|
+
end
|
27
|
+
|
28
|
+
def use!
|
29
|
+
raise AccessTokenUnavailable unless available?
|
30
|
+
revoke_other_access_tokens_under_the_session!
|
31
|
+
end
|
32
|
+
|
33
|
+
def revoke!
|
34
|
+
update_attributes!(revoked_at: Time.current)
|
35
|
+
end
|
36
|
+
|
37
|
+
def revoke_other_access_tokens_under_the_session!
|
38
|
+
oauth_session.oauth_access_tokens.not_revoked.where.not(id: id).update_all(revoked_at: Time.current)
|
39
|
+
end
|
40
|
+
|
41
|
+
class AccessTokenUnavailable < StandardError
|
42
|
+
def initialize
|
43
|
+
super('The access token is unavailable and can not be used.')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def init_token
|
50
|
+
self.token ||= SecureRandom.hex(64)
|
51
|
+
end
|
52
|
+
|
53
|
+
def init_refresh_token
|
54
|
+
self.refresh_token ||= SecureRandom.hex(64)
|
55
|
+
end
|
56
|
+
|
57
|
+
def init_expires_in
|
58
|
+
self.expires_in ||= AuthProvider.configuration.access_token_expiration_time
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module AuthProvider
|
2
|
+
class OAuthSession < ApplicationRecord
|
3
|
+
self.table_name = :oauth_sessions
|
4
|
+
|
5
|
+
scope :available, -> { where(revoked_at: nil) }
|
6
|
+
|
7
|
+
belongs_to :resource_owner, polymorphic: true, required: true
|
8
|
+
has_many :oauth_access_tokens
|
9
|
+
|
10
|
+
def available?
|
11
|
+
!revoked?
|
12
|
+
end
|
13
|
+
|
14
|
+
def revoked?
|
15
|
+
revoked_at.present?
|
16
|
+
end
|
17
|
+
|
18
|
+
def revoke!
|
19
|
+
update_attributes!(revoked_at: Time.current)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Auth provider</title>
|
5
|
+
<%= stylesheet_link_tag "auth_provider/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "auth_provider/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
class CreateAuthProviderOAuthSessions < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :oauth_sessions do |t|
|
4
|
+
t.integer :resource_owner_id, null: false
|
5
|
+
t.string :resource_owner_type, null: false
|
6
|
+
|
7
|
+
t.string :device_name
|
8
|
+
t.string :device_type
|
9
|
+
t.text :device_identifier
|
10
|
+
|
11
|
+
t.datetime :created_at, null: false
|
12
|
+
t.datetime :revoked_at
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :oauth_sessions, :resource_owner_id
|
16
|
+
add_index :oauth_sessions, :resource_owner_type
|
17
|
+
add_index :oauth_sessions, :device_type
|
18
|
+
add_index :oauth_sessions, :revoked_at
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CreateAuthProviderOAuthAccessTokens < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :oauth_access_tokens do |t|
|
4
|
+
t.integer :oauth_session_id, null: false
|
5
|
+
t.text :token, null: false
|
6
|
+
t.text :refresh_token
|
7
|
+
t.integer :expires_in, null: false
|
8
|
+
|
9
|
+
t.datetime :created_at, null: false
|
10
|
+
t.datetime :revoked_at
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :oauth_access_tokens, :oauth_session_id
|
14
|
+
add_index :oauth_access_tokens, :token, unique: true
|
15
|
+
add_index :oauth_access_tokens, :refresh_token, unique: true
|
16
|
+
add_index :oauth_access_tokens, :revoked_at
|
17
|
+
|
18
|
+
add_foreign_key :oauth_access_tokens, :auth_provider_oauth_sessions
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module AuthProvider
|
2
|
+
class MissingConfiguration < StandardError
|
3
|
+
def initialize
|
4
|
+
super('Configuration for auth_provider is missing. Make sure you have run `rails generate auth_provider:install`.')
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def configure(&block)
|
10
|
+
@config = Config::Builder.new(&block).build
|
11
|
+
end
|
12
|
+
|
13
|
+
def configuration
|
14
|
+
@config || (raise MissingConfiguration)
|
15
|
+
end
|
16
|
+
|
17
|
+
alias config configuration
|
18
|
+
end
|
19
|
+
|
20
|
+
class Config
|
21
|
+
# Configurations
|
22
|
+
attr_accessor :default_resource_owner_type
|
23
|
+
attr_accessor :resource_owner_from_credentials
|
24
|
+
attr_accessor :access_token_expiration_time
|
25
|
+
|
26
|
+
class Builder
|
27
|
+
def initialize(&block)
|
28
|
+
@config = Config.new
|
29
|
+
|
30
|
+
instance_eval(&block)
|
31
|
+
|
32
|
+
# Define default
|
33
|
+
@config.default_resource_owner_type ||= 'User'
|
34
|
+
@config.access_token_expiration_time ||= 2.hours
|
35
|
+
end
|
36
|
+
|
37
|
+
def build
|
38
|
+
@config
|
39
|
+
end
|
40
|
+
|
41
|
+
# Configuration methods
|
42
|
+
|
43
|
+
def default_resource_owner_type(type)
|
44
|
+
@config.default_resource_owner_type = type.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def resource_owner_from_credentials(&block)
|
48
|
+
@config.resource_owner_from_credentials = block
|
49
|
+
end
|
50
|
+
|
51
|
+
def access_token_expires_in(time)
|
52
|
+
@config.access_token_expiration_time = time
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module AuthProvider
|
2
|
+
def self.resource_owner_from_token(token)
|
3
|
+
oauth_access_token = OAuthAccessToken.find_by(token: token)
|
4
|
+
return nil if oauth_access_token.blank? || !oauth_access_token.valid?
|
5
|
+
oauth_access_token.use!
|
6
|
+
oauth_access_token.resource_owner
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module AuthProvider
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
source_root File.expand_path("../templates", __FILE__)
|
8
|
+
|
9
|
+
desc "Creates the AuthProvider initializer and mounts AuthProvider::Engine."
|
10
|
+
|
11
|
+
def copy_migration_file
|
12
|
+
migration_template "create_auth_provider_tables.rb", "db/migrate/create_auth_provider_tables.rb"
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_initializer_file
|
16
|
+
template "auth_provider.rb", "config/initializers/auth_provider.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
def mount_engine
|
20
|
+
route "mount AuthProvider::Engine => '/oauth'"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.next_migration_number(dirname)
|
24
|
+
if defined? ActiveRecord::Generators::Base
|
25
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
26
|
+
elsif defined? ActiveRecord::Migration
|
27
|
+
next_migration_number = current_migration_number(dirname) + 1
|
28
|
+
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
29
|
+
else
|
30
|
+
fail "Can't find a implementation of next_migration_number"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module AuthProvider
|
4
|
+
module Generators
|
5
|
+
class MigrationGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
source_root File.expand_path("../templates", __FILE__)
|
8
|
+
|
9
|
+
desc "Creates the AuthProvider migration file."
|
10
|
+
|
11
|
+
def copy_migration_file
|
12
|
+
migration_template "create_auth_provider_tables.rb", "db/migrate/create_auth_provider_tables.rb"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.next_migration_number(dirname)
|
16
|
+
if defined? ActiveRecord::Generators::Base
|
17
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
18
|
+
elsif defined? ActiveRecord::Migration
|
19
|
+
next_migration_number = current_migration_number(dirname) + 1
|
20
|
+
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
21
|
+
else
|
22
|
+
fail "Can't find a implementation of next_migration_number"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
AuthProvider.configure do
|
2
|
+
# Set the default type of the resource owner
|
3
|
+
default_resource_owner_type "User"
|
4
|
+
|
5
|
+
# This block will be called to get the authenticated resource owner
|
6
|
+
# by his/her credentials
|
7
|
+
resource_owner_from_credentials do |type, username, password|
|
8
|
+
fail "Please configure auth_provider resource_owner_from_credentials in #{__FILE__}"
|
9
|
+
# Put the resource owner authentication logic here.
|
10
|
+
#
|
11
|
+
# The "type" parameter is the resource owner type specified by the request
|
12
|
+
# or the default_resource_owner_type if not specified.
|
13
|
+
#
|
14
|
+
# Example implementation:
|
15
|
+
#
|
16
|
+
# resource_owner_class = case type
|
17
|
+
# when "User"
|
18
|
+
# User
|
19
|
+
# when "AdminUser"
|
20
|
+
# AdminUser
|
21
|
+
# end
|
22
|
+
# resource_owner = resource_owner_class.find_for_database_authentication(email: username)
|
23
|
+
# if resource_owner.valid_password?(password)
|
24
|
+
# resource_owner
|
25
|
+
# else
|
26
|
+
# nil
|
27
|
+
# end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Access token expiration time (defaults to 2 hours)
|
31
|
+
# access_token_expires_in 2.hours
|
32
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class CreateAuthProviderTables < ActiveRecord::Migration[4.2]
|
2
|
+
def change
|
3
|
+
create_table :oauth_sessions do |t|
|
4
|
+
t.integer :resource_owner_id, null: false
|
5
|
+
t.string :resource_owner_type, null: false
|
6
|
+
|
7
|
+
t.string :device_name
|
8
|
+
t.string :device_type
|
9
|
+
t.text :device_identifier
|
10
|
+
|
11
|
+
t.datetime :created_at, null: false
|
12
|
+
t.datetime :revoked_at
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :oauth_sessions, :resource_owner_id
|
16
|
+
add_index :oauth_sessions, :resource_owner_type
|
17
|
+
add_index :oauth_sessions, :device_type
|
18
|
+
add_index :oauth_sessions, :revoked_at
|
19
|
+
|
20
|
+
create_table :oauth_access_tokens do |t|
|
21
|
+
t.integer :oauth_session_id, null: false
|
22
|
+
t.text :token, null: false
|
23
|
+
t.text :refresh_token
|
24
|
+
t.integer :expires_in, null: false
|
25
|
+
|
26
|
+
t.datetime :created_at, null: false
|
27
|
+
t.datetime :revoked_at
|
28
|
+
end
|
29
|
+
|
30
|
+
add_index :oauth_access_tokens, :oauth_session_id
|
31
|
+
add_index :oauth_access_tokens, :token, unique: true
|
32
|
+
add_index :oauth_access_tokens, :refresh_token, unique: true
|
33
|
+
add_index :oauth_access_tokens, :revoked_at
|
34
|
+
|
35
|
+
add_foreign_key :oauth_access_tokens, :auth_provider_oauth_sessions
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: auth_provider
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pokai Chang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.2'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.2'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: appraisal
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: sqlite3
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec-rails
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: database_cleaner
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: simplecov
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: coveralls
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
description:
|
118
|
+
email:
|
119
|
+
- pokaichang72@gmail.com
|
120
|
+
executables: []
|
121
|
+
extensions: []
|
122
|
+
extra_rdoc_files: []
|
123
|
+
files:
|
124
|
+
- MIT-LICENSE
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- app/assets/config/auth_provider_manifest.js
|
128
|
+
- app/assets/javascripts/auth_provider/application.js
|
129
|
+
- app/assets/stylesheets/auth_provider/application.css
|
130
|
+
- app/controllers/auth_provider/application_controller.rb
|
131
|
+
- app/controllers/auth_provider/tokens_controller.rb
|
132
|
+
- app/helpers/auth_provider/application_helper.rb
|
133
|
+
- app/jobs/auth_provider/application_job.rb
|
134
|
+
- app/mailers/auth_provider/application_mailer.rb
|
135
|
+
- app/models/auth_provider/application_record.rb
|
136
|
+
- app/models/auth_provider/oauth_access_token.rb
|
137
|
+
- app/models/auth_provider/oauth_session.rb
|
138
|
+
- app/views/layouts/auth_provider/application.html.erb
|
139
|
+
- config/initializers/inflections.rb
|
140
|
+
- config/routes.rb
|
141
|
+
- db/migrate/20161119091649_create_auth_provider_oauth_sessions.rb
|
142
|
+
- db/migrate/20161119092930_create_auth_provider_oauth_access_tokens.rb
|
143
|
+
- lib/auth_provider.rb
|
144
|
+
- lib/auth_provider/config.rb
|
145
|
+
- lib/auth_provider/engine.rb
|
146
|
+
- lib/auth_provider/resource_owner_from_token.rb
|
147
|
+
- lib/auth_provider/version.rb
|
148
|
+
- lib/generators/auth_provider/install_generator.rb
|
149
|
+
- lib/generators/auth_provider/migration_generator.rb
|
150
|
+
- lib/generators/auth_provider/templates/auth_provider.rb
|
151
|
+
- lib/generators/auth_provider/templates/create_auth_provider_tables.rb
|
152
|
+
- lib/tasks/auth_provider_tasks.rake
|
153
|
+
homepage:
|
154
|
+
licenses:
|
155
|
+
- MIT
|
156
|
+
metadata: {}
|
157
|
+
post_install_message:
|
158
|
+
rdoc_options: []
|
159
|
+
require_paths:
|
160
|
+
- lib
|
161
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
requirements: []
|
172
|
+
rubyforge_project:
|
173
|
+
rubygems_version: 2.6.8
|
174
|
+
signing_key:
|
175
|
+
specification_version: 4
|
176
|
+
summary: Auth provider for Rails.
|
177
|
+
test_files: []
|