sso 0.0.2 → 0.1.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|