sso 0.0.2 → 0.1.0.alpha1
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 +4 -4
- data/lib/sso.rb +6 -0
- data/spec/dummy/Rakefile +9 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/home_controller.rb +4 -0
- data/spec/dummy/app/controllers/sessions_controller.rb +39 -0
- data/spec/dummy/app/models/user.rb +9 -0
- data/spec/dummy/app/views/home/index.html.erb +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/sessions/new.html.erb +10 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +36 -0
- data/spec/dummy/config/boot.rb +4 -0
- data/spec/dummy/config/database.yml +38 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +23 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/secret_token.rb +10 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/sso.rb +37 -0
- data/spec/dummy/config/initializers/warden.rb +29 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/doorkeeper.en.yml +151 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +12 -0
- data/spec/dummy/db/migrate/20150302113121_add_users.rb +14 -0
- data/spec/dummy/db/migrate/20150303054803_create_doorkeeper_tables.rb +51 -0
- data/spec/dummy/db/migrate/20150303132931_create_passports_table.rb +38 -0
- data/spec/dummy/db/schema.rb +97 -0
- data/spec/integration/oauth/after_fetch_spec.rb +43 -0
- data/spec/integration/oauth/authorization_code_spec.rb +56 -0
- data/spec/integration/oauth/password_verification_spec.rb +67 -0
- data/spec/lib/sso/logging_spec.rb +39 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/support/factories/doorkeeper/application.rb +21 -0
- data/spec/support/factories/server/passport.rb +10 -0
- data/spec/support/factories/server/user.rb +14 -0
- data/spec/support/sso/test.rb +9 -0
- data/spec/support/sso/test/cookie_stripper.rb +20 -0
- data/spec/support/sso/test/helpers.rb +56 -0
- metadata +283 -17
@@ -0,0 +1,37 @@
|
|
1
|
+
# POI
|
2
|
+
|
3
|
+
# This is the minimal configuration you need to do for using the sso gem.
|
4
|
+
|
5
|
+
SSO.configure do |config|
|
6
|
+
|
7
|
+
config.find_user_for_passport = proc do |passport, ip|
|
8
|
+
# This is your chance to modify the user instance before it is handed out to the OAuth client apps.
|
9
|
+
|
10
|
+
progname = 'SSO.config.find_user_for_passport'
|
11
|
+
Rails.logger.debug(progname) { "Looking up User #{passport.owner_id} belonging to Passport #{passport.id} surfing with IP #{ip}..." }
|
12
|
+
user = User.find_by_id passport.owner_id
|
13
|
+
return unless user
|
14
|
+
|
15
|
+
# The IP address, for example, might be used to set certain flags on the user object.
|
16
|
+
# If these flags are included in the #user_state base (see below), all OAuth client apps are immediately aware of the change.
|
17
|
+
if ip == '198.51.100.74'
|
18
|
+
user.tags << :is_at_the_office
|
19
|
+
else
|
20
|
+
user.tags << :is_working_from_home
|
21
|
+
end
|
22
|
+
|
23
|
+
user
|
24
|
+
end
|
25
|
+
|
26
|
+
config.user_state_base = proc do |user|
|
27
|
+
# Include the end-user credentials to force all OAuth client apps to refetch the end-user Passports.
|
28
|
+
# This way you can revoke all relevant Passports on SSO-logout and the OAuth client apps are immediately aware of it.
|
29
|
+
[user.email, user.password, user.tags.sort].join
|
30
|
+
end
|
31
|
+
|
32
|
+
# This is a rather static key used to calculate whether a user state changed and needs to be propagated to the OAuth clients.
|
33
|
+
# It's not a problem if this changes, as long as it's somewhat deterministic.
|
34
|
+
# In our case, we simply derive it from the Rails secret_key_base so we don't have to remember yet another secret somewhere.
|
35
|
+
generator = ActiveSupport::KeyGenerator.new Rails.application.config.secret_key_base, iterations: 1000
|
36
|
+
config.user_state_key = Rails.application.config.user_state_digest_key = generator.generate_key 'user state digest key'
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# POI
|
2
|
+
::Warden::Strategies.add :password do
|
3
|
+
def valid?
|
4
|
+
params['username'].present?
|
5
|
+
end
|
6
|
+
|
7
|
+
def authenticate!
|
8
|
+
Rails.logger.debug(progname) { 'Authenticating from username and password...' }
|
9
|
+
|
10
|
+
user = ::User.authenticate params['username'], params['password']
|
11
|
+
|
12
|
+
if user
|
13
|
+
Rails.logger.debug(progname) { 'Authentication from username and password successful.' }
|
14
|
+
success! user
|
15
|
+
else
|
16
|
+
Rails.logger.debug(progname) { 'Authentication from username and password failed.' }
|
17
|
+
fail! 'Could not login.'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def progname
|
22
|
+
'Warden::Strategies.password'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# POI
|
27
|
+
Warden::Manager.after_authentication(&::SSO::Server::Warden::Hooks::AfterAuthentication.to_proc)
|
28
|
+
Warden::Manager.before_logout(&::SSO::Server::Warden::Hooks::BeforeLogout.to_proc)
|
29
|
+
Warden::Strategies.add :passport, ::SSO::Server::Warden::Strategies::Passport
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# This file contains settings for ActionController::ParamsWrapper which
|
4
|
+
# is enabled by default.
|
5
|
+
|
6
|
+
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
|
9
|
+
end
|
10
|
+
|
11
|
+
# To enable root element in JSON for ActiveRecord objects.
|
12
|
+
# ActiveSupport.on_load(:active_record) do
|
13
|
+
# self.include_root_in_json = true
|
14
|
+
# end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
en:
|
2
|
+
activerecord:
|
3
|
+
attributes:
|
4
|
+
doorkeeper/application:
|
5
|
+
name: 'Name'
|
6
|
+
redirect_uri: 'Redirect URI'
|
7
|
+
errors:
|
8
|
+
models:
|
9
|
+
doorkeeper/application:
|
10
|
+
attributes:
|
11
|
+
redirect_uri:
|
12
|
+
fragment_present: 'cannot contain a fragment.'
|
13
|
+
invalid_uri: 'must be a valid URI.'
|
14
|
+
relative_uri: 'must be an absolute URI.'
|
15
|
+
secured_uri: 'must be an HTTPS/SSL URI.'
|
16
|
+
|
17
|
+
mongoid:
|
18
|
+
attributes:
|
19
|
+
doorkeeper/application:
|
20
|
+
name: 'Name'
|
21
|
+
redirect_uri: 'Redirect URI'
|
22
|
+
errors:
|
23
|
+
models:
|
24
|
+
doorkeeper/application:
|
25
|
+
attributes:
|
26
|
+
redirect_uri:
|
27
|
+
fragment_present: 'cannot contain a fragment.'
|
28
|
+
invalid_uri: 'must be a valid URI.'
|
29
|
+
relative_uri: 'must be an absolute URI.'
|
30
|
+
secured_uri: 'must be an HTTPS/SSL URI.'
|
31
|
+
|
32
|
+
mongo_mapper:
|
33
|
+
attributes:
|
34
|
+
doorkeeper/application:
|
35
|
+
name: 'Name'
|
36
|
+
redirect_uri: 'Redirect URI'
|
37
|
+
errors:
|
38
|
+
models:
|
39
|
+
doorkeeper/application:
|
40
|
+
attributes:
|
41
|
+
redirect_uri:
|
42
|
+
fragment_present: 'cannot contain a fragment.'
|
43
|
+
invalid_uri: 'must be a valid URI.'
|
44
|
+
relative_uri: 'must be an absolute URI.'
|
45
|
+
secured_uri: 'must be an HTTPS/SSL URI.'
|
46
|
+
|
47
|
+
doorkeeper:
|
48
|
+
applications:
|
49
|
+
confirmations:
|
50
|
+
destroy: 'Are you sure?'
|
51
|
+
buttons:
|
52
|
+
edit: 'Edit'
|
53
|
+
destroy: 'Destroy'
|
54
|
+
submit: 'Submit'
|
55
|
+
cancel: 'Cancel'
|
56
|
+
authorize: 'Authorize'
|
57
|
+
form:
|
58
|
+
error: 'Whoops! Check your form for possible errors'
|
59
|
+
help:
|
60
|
+
redirect_uri: 'Use one line per URI'
|
61
|
+
native_redirect_uri: 'Use %{native_redirect_uri} for local tests'
|
62
|
+
edit:
|
63
|
+
title: 'Edit application'
|
64
|
+
index:
|
65
|
+
title: 'Your applications'
|
66
|
+
new: 'New Application'
|
67
|
+
name: 'Name'
|
68
|
+
callback_url: 'Callback URL'
|
69
|
+
new:
|
70
|
+
title: 'New Application'
|
71
|
+
show:
|
72
|
+
title: 'Application: %{name}'
|
73
|
+
application_id: 'Application Id'
|
74
|
+
secret: 'Secret'
|
75
|
+
callback_urls: 'Callback urls'
|
76
|
+
actions: 'Actions'
|
77
|
+
|
78
|
+
authorizations:
|
79
|
+
buttons:
|
80
|
+
authorize: 'Authorize'
|
81
|
+
deny: 'Deny'
|
82
|
+
error:
|
83
|
+
title: 'An error has occurred'
|
84
|
+
new:
|
85
|
+
title: 'Authorize required'
|
86
|
+
prompt: 'Authorize %{client_name} to use your account?'
|
87
|
+
able_to: 'This application will be able to'
|
88
|
+
show:
|
89
|
+
title: 'Authorization code'
|
90
|
+
|
91
|
+
authorized_applications:
|
92
|
+
confirmations:
|
93
|
+
revoke: 'Are you sure?'
|
94
|
+
buttons:
|
95
|
+
revoke: 'Revoke'
|
96
|
+
index:
|
97
|
+
title: 'Your authorized applications'
|
98
|
+
application: 'Application'
|
99
|
+
created_at: 'Created At'
|
100
|
+
date_format: '%Y-%m-%d %H:%M:%S'
|
101
|
+
|
102
|
+
errors:
|
103
|
+
messages:
|
104
|
+
# Common error messages
|
105
|
+
invalid_request: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
|
106
|
+
invalid_redirect_uri: 'The redirect uri included is not valid.'
|
107
|
+
unauthorized_client: 'The client is not authorized to perform this request using this method.'
|
108
|
+
access_denied: 'The resource owner or authorization server denied the request.'
|
109
|
+
invalid_scope: 'The requested scope is invalid, unknown, or malformed.'
|
110
|
+
server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.'
|
111
|
+
temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'
|
112
|
+
|
113
|
+
#configuration error messages
|
114
|
+
credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.'
|
115
|
+
resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.'
|
116
|
+
|
117
|
+
# Access grant errors
|
118
|
+
unsupported_response_type: 'The authorization server does not support this response type.'
|
119
|
+
|
120
|
+
# Access token errors
|
121
|
+
invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.'
|
122
|
+
invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.'
|
123
|
+
unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.'
|
124
|
+
|
125
|
+
# Password Access token errors
|
126
|
+
invalid_resource_owner: 'The provided resource owner credentials are not valid, or resource owner cannot be found'
|
127
|
+
|
128
|
+
invalid_token:
|
129
|
+
revoked: "The access token was revoked"
|
130
|
+
expired: "The access token expired"
|
131
|
+
unknown: "The access token is invalid"
|
132
|
+
|
133
|
+
flash:
|
134
|
+
applications:
|
135
|
+
create:
|
136
|
+
notice: 'Application created.'
|
137
|
+
destroy:
|
138
|
+
notice: 'Application deleted.'
|
139
|
+
update:
|
140
|
+
notice: 'Application updated.'
|
141
|
+
authorized_applications:
|
142
|
+
destroy:
|
143
|
+
notice: 'Application revoked.'
|
144
|
+
|
145
|
+
layouts:
|
146
|
+
admin:
|
147
|
+
nav:
|
148
|
+
oauth2_provider: 'OAuth2 Provider'
|
149
|
+
applications: 'Applications'
|
150
|
+
application:
|
151
|
+
title: 'OAuth authorize required'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Files in the config/locales directory are used for internationalization
|
2
|
+
# and are automatically loaded by Rails. If you want to use locales other
|
3
|
+
# than English, add the necessary files in this directory.
|
4
|
+
#
|
5
|
+
# To use the locales, use `I18n.t`:
|
6
|
+
#
|
7
|
+
# I18n.t 'hello'
|
8
|
+
#
|
9
|
+
# In views, this is aliased to just `t`:
|
10
|
+
#
|
11
|
+
# <%= t('hello') %>
|
12
|
+
#
|
13
|
+
# To use a different locale, set it with `I18n.locale`:
|
14
|
+
#
|
15
|
+
# I18n.locale = :es
|
16
|
+
#
|
17
|
+
# This would use the information in config/locales/es.yml.
|
18
|
+
#
|
19
|
+
# To learn more, please read the Rails Internationalization guide
|
20
|
+
# available at http://guides.rubyonrails.org/i18n.html.
|
21
|
+
|
22
|
+
en:
|
23
|
+
hello: "Hello world"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
|
3
|
+
use_doorkeeper do
|
4
|
+
skip_controllers :applications, :authorized_applications
|
5
|
+
end
|
6
|
+
|
7
|
+
resources :sessions, only: [:new, :create]
|
8
|
+
get '/logout(/:passport_id)', to: 'sessions#logout', as: :logout
|
9
|
+
|
10
|
+
root to: 'home#index'
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This is not part of SSO, this is simply an example implementation of a user model.
|
2
|
+
|
3
|
+
class AddUsers < ActiveRecord::Migration
|
4
|
+
def change
|
5
|
+
create_table :users do |t|
|
6
|
+
t.string :name, null: false
|
7
|
+
t.string :email, null: false
|
8
|
+
t.string :password, null: false # <- Of course you would have this encrypted in a real-life setup
|
9
|
+
t.string :tags, array: true, default: []
|
10
|
+
t.boolean :vip
|
11
|
+
t.timestamps null: false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# POI
|
2
|
+
|
3
|
+
# This migration file is created when you run `rails generate doorkeeper:install` in your OAuth Server Rails app.
|
4
|
+
# These tables are needed for Doorkeeper to work, see also https://github.com/doorkeeper-gem/doorkeeper#installation
|
5
|
+
# This migration here has *not* been modified. You simply see the original file below, created by the Doorkeeper generator.
|
6
|
+
|
7
|
+
# Note, however, that it was generated with Doorkeeper >= 2.0.0, since it has the `scopes` column on the `oauth_applications` table.
|
8
|
+
# We make use of that column and it was introduced here: https://github.com/doorkeeper-gem/doorkeeper/blob/master/CHANGELOG.md#200
|
9
|
+
|
10
|
+
class CreateDoorkeeperTables < ActiveRecord::Migration
|
11
|
+
def change
|
12
|
+
create_table :oauth_applications do |t|
|
13
|
+
t.string :name, null: false
|
14
|
+
t.string :uid, null: false
|
15
|
+
t.string :secret, null: false
|
16
|
+
t.text :redirect_uri, null: false
|
17
|
+
t.string :scopes, null: false, default: '' # <- Exists only with Doorkeeper 2.0.0 or higher.
|
18
|
+
t.timestamps null: false
|
19
|
+
end
|
20
|
+
|
21
|
+
add_index :oauth_applications, :uid, unique: true
|
22
|
+
|
23
|
+
create_table :oauth_access_grants do |t|
|
24
|
+
t.integer :resource_owner_id, null: false
|
25
|
+
t.integer :application_id, null: false
|
26
|
+
t.string :token, null: false
|
27
|
+
t.integer :expires_in, null: false
|
28
|
+
t.text :redirect_uri, null: false
|
29
|
+
t.datetime :created_at, null: false
|
30
|
+
t.datetime :revoked_at
|
31
|
+
t.string :scopes
|
32
|
+
end
|
33
|
+
|
34
|
+
add_index :oauth_access_grants, :token, unique: true
|
35
|
+
|
36
|
+
create_table :oauth_access_tokens do |t|
|
37
|
+
t.integer :resource_owner_id
|
38
|
+
t.integer :application_id
|
39
|
+
t.string :token, null: false
|
40
|
+
t.string :refresh_token
|
41
|
+
t.integer :expires_in
|
42
|
+
t.datetime :revoked_at
|
43
|
+
t.datetime :created_at, null: false
|
44
|
+
t.string :scopes
|
45
|
+
end
|
46
|
+
|
47
|
+
add_index :oauth_access_tokens, :token, unique: true
|
48
|
+
add_index :oauth_access_tokens, :resource_owner_id
|
49
|
+
add_index :oauth_access_tokens, :refresh_token, unique: true
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# POI
|
2
|
+
|
3
|
+
# This is what the Passport table on the SSO Server looks like. You need to have this migration.
|
4
|
+
# As you can see it uses the `uuid` and `inet` column types. So you are kind of stuck with Postgres.
|
5
|
+
# However, there should be no reason for you not to simply use `integer` and `string` for those two columns instead.
|
6
|
+
|
7
|
+
class CreatePassportsTable < ActiveRecord::Migration
|
8
|
+
def change
|
9
|
+
enable_extension 'uuid-ossp'
|
10
|
+
|
11
|
+
create_table :passports, id: :uuid do |t|
|
12
|
+
t.integer :oauth_access_grant_id
|
13
|
+
t.integer :oauth_access_token_id
|
14
|
+
t.integer :application_id, null: false
|
15
|
+
t.integer :owner_id, null: false
|
16
|
+
t.string :group_id, null: false
|
17
|
+
t.string :secret, null: false, unique: true
|
18
|
+
t.inet :ip, null: false
|
19
|
+
t.string :agent
|
20
|
+
t.string :location
|
21
|
+
t.datetime :activity_at, null: false
|
22
|
+
t.datetime :revoked_at
|
23
|
+
t.string :revoke_reason
|
24
|
+
t.timestamps null: false
|
25
|
+
end
|
26
|
+
|
27
|
+
add_index :passports, [:owner_id, :oauth_access_token_id], where: 'revoked_at IS NULL AND oauth_access_token_id IS NOT NULL', unique: true, name: :one_access_token_per_owner
|
28
|
+
|
29
|
+
add_index :passports, :oauth_access_grant_id
|
30
|
+
add_index :passports, :oauth_access_token_id
|
31
|
+
add_index :passports, :application_id
|
32
|
+
add_index :passports, :owner_id
|
33
|
+
add_index :passports, :group_id
|
34
|
+
add_index :passports, :secret
|
35
|
+
add_index :passports, :ip
|
36
|
+
add_index :passports, :revoke_reason
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(version: 20150303132931) do
|
15
|
+
|
16
|
+
# These are extensions that must be enabled in order to support this database
|
17
|
+
enable_extension "plpgsql"
|
18
|
+
enable_extension "uuid-ossp"
|
19
|
+
|
20
|
+
create_table "oauth_access_grants", force: :cascade do |t|
|
21
|
+
t.integer "resource_owner_id", null: false
|
22
|
+
t.integer "application_id", null: false
|
23
|
+
t.string "token", null: false
|
24
|
+
t.integer "expires_in", null: false
|
25
|
+
t.text "redirect_uri", null: false
|
26
|
+
t.datetime "created_at", null: false
|
27
|
+
t.datetime "revoked_at"
|
28
|
+
t.string "scopes"
|
29
|
+
end
|
30
|
+
|
31
|
+
add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree
|
32
|
+
|
33
|
+
create_table "oauth_access_tokens", force: :cascade do |t|
|
34
|
+
t.integer "resource_owner_id"
|
35
|
+
t.integer "application_id"
|
36
|
+
t.string "token", null: false
|
37
|
+
t.string "refresh_token"
|
38
|
+
t.integer "expires_in"
|
39
|
+
t.datetime "revoked_at"
|
40
|
+
t.datetime "created_at", null: false
|
41
|
+
t.string "scopes"
|
42
|
+
end
|
43
|
+
|
44
|
+
add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree
|
45
|
+
add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree
|
46
|
+
add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree
|
47
|
+
|
48
|
+
create_table "oauth_applications", force: :cascade do |t|
|
49
|
+
t.string "name", null: false
|
50
|
+
t.string "uid", null: false
|
51
|
+
t.string "secret", null: false
|
52
|
+
t.text "redirect_uri", null: false
|
53
|
+
t.string "scopes", default: "", null: false
|
54
|
+
t.datetime "created_at", null: false
|
55
|
+
t.datetime "updated_at", null: false
|
56
|
+
end
|
57
|
+
|
58
|
+
add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree
|
59
|
+
|
60
|
+
create_table "passports", id: :uuid, default: "uuid_generate_v4()", force: :cascade do |t|
|
61
|
+
t.integer "oauth_access_grant_id"
|
62
|
+
t.integer "oauth_access_token_id"
|
63
|
+
t.integer "application_id", null: false
|
64
|
+
t.integer "owner_id", null: false
|
65
|
+
t.string "group_id", null: false
|
66
|
+
t.string "secret", null: false
|
67
|
+
t.inet "ip", null: false
|
68
|
+
t.string "agent"
|
69
|
+
t.string "location"
|
70
|
+
t.datetime "activity_at", null: false
|
71
|
+
t.datetime "revoked_at"
|
72
|
+
t.string "revoke_reason"
|
73
|
+
t.datetime "created_at", null: false
|
74
|
+
t.datetime "updated_at", null: false
|
75
|
+
end
|
76
|
+
|
77
|
+
add_index "passports", ["application_id"], name: "index_passports_on_application_id", using: :btree
|
78
|
+
add_index "passports", ["group_id"], name: "index_passports_on_group_id", using: :btree
|
79
|
+
add_index "passports", ["ip"], name: "index_passports_on_ip", using: :btree
|
80
|
+
add_index "passports", ["oauth_access_grant_id"], name: "index_passports_on_oauth_access_grant_id", using: :btree
|
81
|
+
add_index "passports", ["oauth_access_token_id"], name: "index_passports_on_oauth_access_token_id", using: :btree
|
82
|
+
add_index "passports", ["owner_id", "oauth_access_token_id"], name: "one_access_token_per_owner", unique: true, where: "((revoked_at IS NULL) AND (oauth_access_token_id IS NOT NULL))", using: :btree
|
83
|
+
add_index "passports", ["owner_id"], name: "index_passports_on_owner_id", using: :btree
|
84
|
+
add_index "passports", ["revoke_reason"], name: "index_passports_on_revoke_reason", using: :btree
|
85
|
+
add_index "passports", ["secret"], name: "index_passports_on_secret", using: :btree
|
86
|
+
|
87
|
+
create_table "users", force: :cascade do |t|
|
88
|
+
t.string "name", null: false
|
89
|
+
t.string "email", null: false
|
90
|
+
t.string "password", null: false
|
91
|
+
t.string "tags", default: [], array: true
|
92
|
+
t.boolean "vip"
|
93
|
+
t.datetime "created_at", null: false
|
94
|
+
t.datetime "updated_at", null: false
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|