auth_provider 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/zetavg/AuthProvider.svg?branch=master)](https://travis-ci.org/zetavg/AuthProvider) [![Coverage Status](https://coveralls.io/repos/github/zetavg/AuthProvider/badge.svg?branch=master)](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: []
|