authify-api 0.4.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/README.md +7 -2
- data/authify-api.gemspec +1 -0
- data/db/migrate/20170711151033_add_handle_to_user.rb +12 -0
- data/db/migrate/20170712101155_add_unique_index_to_groups.rb +6 -0
- data/db/migrate/20170712101438_add_unique_index_to_identities.rb +6 -0
- data/db/migrate/20170712103319_add_unique_index_to_organizations.rb +6 -0
- data/db/migrate/20170712103320_add_unique_index_to_users.rb +6 -0
- data/db/migrate/20170714051226_set_default_handle_on_users.rb +16 -0
- data/db/schema.rb +7 -1
- data/lib/authify/api.rb +3 -0
- data/lib/authify/api/controllers/trusted_delegate.rb +48 -0
- data/lib/authify/api/controllers/user.rb +3 -2
- data/lib/authify/api/helpers/text_processing.rb +2 -3
- data/lib/authify/api/models/group.rb +2 -0
- data/lib/authify/api/models/identity.rb +2 -0
- data/lib/authify/api/models/organization.rb +2 -0
- data/lib/authify/api/models/trusted_delegate.rb +1 -0
- data/lib/authify/api/models/user.rb +21 -3
- data/lib/authify/api/serializers/trusted_delegate_serializer.rb +19 -0
- data/lib/authify/api/serializers/user_serializer.rb +1 -0
- data/lib/authify/api/services/api.rb +1 -0
- data/lib/authify/api/services/registration.rb +10 -2
- data/lib/authify/api/version.rb +2 -2
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5033995f7f6ff20f2149dc9f334c65b05448f4ae
|
4
|
+
data.tar.gz: 91c04c240880c69e414e3798c8233736855208cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5892be4a3773859531a761a9d38bc45f1436def5c6e98917e58400806728affc775b1a62a92c946226e7ba611781059fb7b63b77489c5e2ceec4d73e61c8bbaf
|
7
|
+
data.tar.gz: e2fa79cc813152f078308a65e4b933389a6097cce821089ce8f9601af6cae39766267a6c450ba1beb9154be40edd4efb2ac8e87d9359e3795321c05334c672d3
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -94,6 +94,9 @@ Alternate User Identities. These are other services that the user can login via
|
|
94
94
|
**`/organizations`**
|
95
95
|
Organizations. These are high-level groupings of users and groups. Non-administrators should only be able to see limited amounts of information about organizations.
|
96
96
|
|
97
|
+
**`/trusted-delegates`**
|
98
|
+
Trusted Delegates. These are heavily-integrated applications that can offload some of the API's functionality (usually getting a user's credentials). All actions on this controller require `admin` access to Authify. See [Trusted Delegates](#trusted_delegates) below for more info.
|
99
|
+
|
97
100
|
**`/users`**
|
98
101
|
Users controller.
|
99
102
|
|
@@ -101,7 +104,7 @@ Users controller.
|
|
101
104
|
|
102
105
|
In addition to expiring JWTs provided via `/jwt/token` for normal user interactions, Trusted Delegates can perform any action by providing the `X-Authify-Access`, `X-Authify-Secret`, and the `X-Authify-On-Behalf-Of` headers. The `Access` and `Secret` headers are used to authenticate the remote application, and the `On-Behalf-Of` is used to impersonate the user (determined through a process on the remote, trusted delegate's end to establish the user's identity).
|
103
106
|
|
104
|
-
Note that while these sound similar to User API keys, these Trusted Delegate credentials are longer and can not be interchanged with User API Keys. These values do not expire and are not easily created or removed. For this reason, they should be used **very** sparingly.
|
107
|
+
Note that while these sound similar to User API keys, these Trusted Delegate credentials are longer and can not be interchanged with User API Keys. These values do not expire and are not easily created or removed. For this reason, they should be used **very** sparingly. In a pinch, they can be created, listed, or removed via a set of `rake` commands run server-side. These are:
|
105
108
|
|
106
109
|
* `rake delegate:add[<name>]` - where `<name>` is the unique name of the trusted delegate. For example, `rake delegate:add[foo]` adds a remote delegate named `foo`. This command will output a key / value set providing the access\_key and secret\_key. The secret\_key is stored as a one-way hash in the DB, so it can never be retrieved again.
|
107
110
|
* `rake delegate:list` - lists the names of all trusted delegates along with their access keys.
|
@@ -201,6 +204,7 @@ This will return JSON similar to the following:
|
|
201
204
|
{
|
202
205
|
"id": 172,
|
203
206
|
"email": "someuser@mycompany.com",
|
207
|
+
"handle": "someuser",
|
204
208
|
"verified": false
|
205
209
|
}
|
206
210
|
```
|
@@ -226,6 +230,7 @@ This will return JSON similar to the following:
|
|
226
230
|
{
|
227
231
|
"id": 172,
|
228
232
|
"email": "someuser@mycompany.com",
|
233
|
+
"handle": "someuser",
|
229
234
|
"verified": true,
|
230
235
|
"jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJleHAiOjE0ODY0ODcyODcsImlhdCI6MTQ4NjQ4MzY4NywiaXNzIjoiTXkgQXdlc29tZSBDb21wYW55IEluYy4iLCJzY29wZXMiOlsidXNlcl9hY2Nlc3MiXSwidXNlciI6eyJ1c2VybmFtZSI6ImZvb0BiYXIuY29tIiwidWlkIjoyLCJvcmdhbml6YXRpb25zIjpbXSwiZ3JvdXBzIjpbXX19.AWfPpKX9mP03Djz3-LMneJdEVsXQm_4GOPVCdkfiiBeIR4pVLKTVrNoNdlNgSEkZEeUw1RPsVxpAR7wDgB4cNcYiAP3fNaD8OPyWfOQAV0lTvDUSH3YU39cZAVwvbX9HleOHBLrFGBbui5wSvfi7WZZlH808psiuUAVhBOe7mfrNiHGB"
|
231
236
|
}
|
@@ -365,7 +370,7 @@ to include a `templates` section like this:
|
|
365
370
|
}
|
366
371
|
```
|
367
372
|
|
368
|
-
Authify's
|
373
|
+
Authify's uses [Liquid](https://shopify.github.io/liquid/) for templating. This is useful for allowing the injection of dynamic data into your templates, and it also supports a robust set of [tags](https://shopify.github.io/liquid/basics/introduction/#tags) for iteration and control flow, as well as [filters](https://shopify.github.io/liquid/basics/introduction/#filters) for manipulating data. Predefined variables and available expressions should be declared in the README section that describes a template-capable endpoint.
|
369
374
|
|
370
375
|
For some template data, escaping can be difficult or inconvenient. For these situations, Authify supports optional [Base64](https://en.wikipedia.org/wiki/Base64) encoding of values. To provide a Base64-encoded value, just declare it as such using `{base64}` followed by the data:
|
371
376
|
|
data/authify-api.gemspec
CHANGED
@@ -38,6 +38,7 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_runtime_dependency 'puma', '~> 3.7'
|
39
39
|
spec.add_runtime_dependency 'resque', '~> 1.26'
|
40
40
|
spec.add_runtime_dependency 'hitimes', '~> 1.2'
|
41
|
+
spec.add_runtime_dependency 'liquid', '~> 4.0'
|
41
42
|
|
42
43
|
spec.add_development_dependency 'bundler', '~> 1.12'
|
43
44
|
spec.add_development_dependency 'rake', '~> 10.0'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Sets a handle for users without one
|
2
|
+
class SetDefaultHandleOnUsers < ActiveRecord::Migration[5.1]
|
3
|
+
def up
|
4
|
+
Authify::API::Models::User.reset_column_information
|
5
|
+
Authify::API::Models::User.all.each do |user|
|
6
|
+
tmp_handle = Authify::API::Models::User.uniq_handle_generator(user.full_name, user.email)
|
7
|
+
user.handle = tmp_handle unless user.handle
|
8
|
+
puts "Setting handle #{user.handle} for User #{user.id}"
|
9
|
+
user.save
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def down
|
14
|
+
# nothing to do
|
15
|
+
end
|
16
|
+
end
|
data/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 20170714051226) do
|
14
14
|
|
15
15
|
create_table "apikeys", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
16
16
|
t.integer "user_id"
|
@@ -28,6 +28,7 @@ ActiveRecord::Schema.define(version: 20170609181046) do
|
|
28
28
|
t.text "description"
|
29
29
|
t.datetime "created_at", null: false
|
30
30
|
t.datetime "updated_at", null: false
|
31
|
+
t.index ["name", "organization_id"], name: "index_groups_on_name_and_organization_id", unique: true
|
31
32
|
t.index ["name"], name: "index_groups_on_name"
|
32
33
|
t.index ["organization_id"], name: "index_groups_on_organization_id"
|
33
34
|
end
|
@@ -46,6 +47,7 @@ ActiveRecord::Schema.define(version: 20170609181046) do
|
|
46
47
|
t.datetime "created_at", null: false
|
47
48
|
t.datetime "updated_at", null: false
|
48
49
|
t.index ["provider"], name: "index_identities_on_provider"
|
50
|
+
t.index ["uid", "provider"], name: "index_identities_on_uid_and_provider", unique: true
|
49
51
|
t.index ["uid"], name: "index_identities_on_uid"
|
50
52
|
t.index ["user_id"], name: "index_identities_on_user_id"
|
51
53
|
end
|
@@ -70,6 +72,7 @@ ActiveRecord::Schema.define(version: 20170609181046) do
|
|
70
72
|
t.datetime "created_at", null: false
|
71
73
|
t.datetime "updated_at", null: false
|
72
74
|
t.index ["name"], name: "index_organizations_on_name"
|
75
|
+
t.index ["name"], name: "index_organizations_unique_on_name", unique: true
|
73
76
|
end
|
74
77
|
|
75
78
|
create_table "trusted_delegates", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
@@ -92,8 +95,11 @@ ActiveRecord::Schema.define(version: 20170609181046) do
|
|
92
95
|
t.boolean "admin", default: false, null: false
|
93
96
|
t.boolean "verified"
|
94
97
|
t.string "verification_token"
|
98
|
+
t.string "handle"
|
95
99
|
t.index ["admin"], name: "index_users_on_admin"
|
96
100
|
t.index ["email"], name: "index_users_on_email"
|
101
|
+
t.index ["email"], name: "index_users_unique_on_email", unique: true
|
102
|
+
t.index ["handle"], name: "index_users_on_handle", unique: true
|
97
103
|
t.index ["verified"], name: "index_users_on_verified"
|
98
104
|
end
|
99
105
|
|
data/lib/authify/api.rb
CHANGED
@@ -13,6 +13,7 @@ require 'connection_pool'
|
|
13
13
|
require 'moneta'
|
14
14
|
require 'resque'
|
15
15
|
require 'hitimes'
|
16
|
+
require 'liquid'
|
16
17
|
|
17
18
|
# Internal Requirements
|
18
19
|
module Authify
|
@@ -41,12 +42,14 @@ require 'authify/api/controllers/apikey'
|
|
41
42
|
require 'authify/api/controllers/group'
|
42
43
|
require 'authify/api/controllers/identity'
|
43
44
|
require 'authify/api/controllers/organization'
|
45
|
+
require 'authify/api/controllers/trusted_delegate'
|
44
46
|
require 'authify/api/controllers/user'
|
45
47
|
require 'authify/api/serializers/apikey_serializer'
|
46
48
|
require 'authify/api/serializers/group_serializer'
|
47
49
|
require 'authify/api/serializers/identity_serializer'
|
48
50
|
require 'authify/api/serializers/user_serializer'
|
49
51
|
require 'authify/api/serializers/organization_serializer'
|
52
|
+
require 'authify/api/serializers/trusted_delegate_serializer'
|
50
53
|
require 'authify/api/helpers/jwt_encryption'
|
51
54
|
require 'authify/api/helpers/api_user'
|
52
55
|
require 'authify/api/helpers/text_processing'
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Authify
|
2
|
+
module API
|
3
|
+
module Controllers
|
4
|
+
TrustedDelegate = proc do
|
5
|
+
helpers do
|
6
|
+
def find(id)
|
7
|
+
Models::TrustedDelegate.find(id.to_i)
|
8
|
+
end
|
9
|
+
|
10
|
+
def modifiable_fields
|
11
|
+
%i[name]
|
12
|
+
end
|
13
|
+
|
14
|
+
def filtered_attributes(attributes)
|
15
|
+
attributes.select do |k, _v|
|
16
|
+
modifiable_fields.include?(k)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
index(roles: %i[admin]) do
|
22
|
+
Models::TrustedDelegate.all
|
23
|
+
end
|
24
|
+
|
25
|
+
show(roles: %i[admin]) do
|
26
|
+
last_modified resource.updated_at
|
27
|
+
next resource, exclude: [:secret_key]
|
28
|
+
end
|
29
|
+
|
30
|
+
create(roles: %i[admin]) do |attrs|
|
31
|
+
key = Models::TrustedDelegate.new filtered_attributes(attrs)
|
32
|
+
key.access_key = Models::TrustedDelegate.generate_access_key
|
33
|
+
key.set_secret!
|
34
|
+
key.save
|
35
|
+
next key.id, key
|
36
|
+
end
|
37
|
+
|
38
|
+
destroy(roles: %i[admin]) do
|
39
|
+
resource.destroy
|
40
|
+
end
|
41
|
+
|
42
|
+
show_many do |ids|
|
43
|
+
Models::TrustedDelegate.find(ids)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -26,17 +26,18 @@ module Authify
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def modifiable_fields
|
29
|
-
%i[full_name email].tap do |a|
|
29
|
+
%i[full_name email handle].tap do |a|
|
30
30
|
a << :admin if role.include?(:admin)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
def indexable_fields
|
35
|
-
%i[full-name admin
|
35
|
+
%i[full-name admin handle groups organizations identities].tap do |a|
|
36
36
|
if role?(:admin) || role?(:myself)
|
37
37
|
a << :verified
|
38
38
|
a << :email
|
39
39
|
a << :'created-at'
|
40
|
+
a << :apikeys
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
@@ -11,10 +11,9 @@ module Authify
|
|
11
11
|
hash.update(hash) { |_, v| v.is_a?(String) ? human_readable(v) : v }
|
12
12
|
end
|
13
13
|
|
14
|
-
# Interpolates handlebars-style templates
|
15
|
-
# OPTIMIZE: this can probably be faster
|
14
|
+
# Interpolates handlebars-style (liquid) templates
|
16
15
|
def dehandlebar(text, data = {})
|
17
|
-
text.
|
16
|
+
Liquid::Template.parse(text).render(data, error_mode: :warn, strict_variables: true)
|
18
17
|
end
|
19
18
|
|
20
19
|
def human_readable(text)
|
@@ -10,6 +10,7 @@ module Authify
|
|
10
10
|
attr_reader :password
|
11
11
|
|
12
12
|
validates_uniqueness_of :email
|
13
|
+
validates_uniqueness_of :handle
|
13
14
|
validates_format_of :email, with: /[-a-z0-9_+\.+]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}/i
|
14
15
|
|
15
16
|
has_many :apikeys,
|
@@ -33,8 +34,9 @@ module Authify
|
|
33
34
|
|
34
35
|
# Encrypts the password into the password_digest attribute.
|
35
36
|
def password=(plain_password)
|
37
|
+
return false unless viable(plain_password)
|
36
38
|
@password = plain_password
|
37
|
-
self.password_digest = salted_sha512(plain_password)
|
39
|
+
self.password_digest = salted_sha512(plain_password)
|
38
40
|
end
|
39
41
|
|
40
42
|
def authenticate(unencrypted_password)
|
@@ -57,7 +59,7 @@ module Authify
|
|
57
59
|
valid_until = valid_time.to_i
|
58
60
|
self.verification_token = "#{token}:#{valid_until}"
|
59
61
|
|
60
|
-
subdata = { token
|
62
|
+
subdata = { 'token' => token, 'valid_until' => valid_time }
|
61
63
|
|
62
64
|
email_opts = {
|
63
65
|
body: if opts.key?(:body)
|
@@ -98,10 +100,26 @@ module Authify
|
|
98
100
|
provided_identity.user if provided_identity
|
99
101
|
end
|
100
102
|
|
103
|
+
def self.uniq_handle_generator(name, email)
|
104
|
+
possibilities = [email.split('@').first.downcase.gsub(/[._-]/, '')]
|
105
|
+
possibilities << name.downcase.gsub(/[.-]/, '_') if name && !name.empty?
|
106
|
+
possibilities.each do |possibility|
|
107
|
+
return possibility unless find_by_handle(possibility)
|
108
|
+
end
|
109
|
+
100.times do
|
110
|
+
possibilities.each do |possibility|
|
111
|
+
rando_num = rand(9999)
|
112
|
+
attempt = "#{possibility.downcase.gsub(/[.-]/, '_')}#{rando_num}"
|
113
|
+
return attempt unless find_by_handle(attempt)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
false # didn't work if we got here
|
117
|
+
end
|
118
|
+
|
101
119
|
private
|
102
120
|
|
103
121
|
def viable(string)
|
104
|
-
string && !string.empty?
|
122
|
+
string && !string.empty? && string.length >= 8
|
105
123
|
end
|
106
124
|
end
|
107
125
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Authify
|
2
|
+
module API
|
3
|
+
module Serializers
|
4
|
+
# JSON API Serializer for TrustedDelegate model
|
5
|
+
class TrustedDelegateSerializer
|
6
|
+
include JSONAPI::Serializer
|
7
|
+
|
8
|
+
def type
|
9
|
+
'trusted-delegates'
|
10
|
+
end
|
11
|
+
|
12
|
+
attribute :name
|
13
|
+
attribute :access_key
|
14
|
+
attribute :secret_key
|
15
|
+
attribute :created_at
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -67,6 +67,7 @@ module Authify
|
|
67
67
|
resource :identities, &Controllers::Identity
|
68
68
|
resource :groups, &Controllers::Group
|
69
69
|
resource :organizations, &Controllers::Organization
|
70
|
+
resource :trusted_delegate, &Controllers::TrustedDelegate
|
70
71
|
resource :users, &Controllers::User
|
71
72
|
|
72
73
|
freeze_jsonapi
|
@@ -48,6 +48,7 @@ module Authify
|
|
48
48
|
|
49
49
|
post '/signup' do
|
50
50
|
email = @parsed_body[:email]
|
51
|
+
handle = @parsed_body[:handle]
|
51
52
|
via = @parsed_body[:via]
|
52
53
|
password = @parsed_body[:password]
|
53
54
|
name = @parsed_body[:name]
|
@@ -57,8 +58,12 @@ module Authify
|
|
57
58
|
halt(403, 'Password Required') unless password || remote_app
|
58
59
|
|
59
60
|
new_user = Models::User.new(email: email)
|
61
|
+
new_user.handle = handle || Models::User.uniq_handle_generator(name, email)
|
60
62
|
new_user.full_name = name if name
|
61
|
-
|
63
|
+
if password
|
64
|
+
new_user.password = password
|
65
|
+
halt(422, 'Invalid password') unless new_user.password
|
66
|
+
end
|
62
67
|
if via && via[:provider] && remote_app
|
63
68
|
new_user.identities.build(
|
64
69
|
provider: via[:provider], uid: via[:uid] ? via[:uid] : email
|
@@ -73,7 +78,7 @@ module Authify
|
|
73
78
|
halt(422, 'Failed to save user') unless new_user.save
|
74
79
|
update_current_user new_user
|
75
80
|
|
76
|
-
response = { id: new_user.id, email: new_user.email }
|
81
|
+
response = { id: new_user.id, email: new_user.email, handle: new_user.handle }
|
77
82
|
if new_user.verified? || !CONFIG[:verifications][:required]
|
78
83
|
response[:verified] = true
|
79
84
|
response[:jwt] = jwt_token(user: new_user)
|
@@ -99,11 +104,14 @@ module Authify
|
|
99
104
|
if token && @parsed_body[:password] && found_user.verify(token)
|
100
105
|
found_user.verified = true
|
101
106
|
found_user.password = @parsed_body[:password]
|
107
|
+
halt(422, 'Invalid password') unless found_user.password == @parsed_body[:password]
|
108
|
+
|
102
109
|
found_user.save
|
103
110
|
Metrics.instance.increment('registration.password.resets')
|
104
111
|
{
|
105
112
|
id: found_user.id,
|
106
113
|
email: found_user.email,
|
114
|
+
handle: found_user.handle,
|
107
115
|
verified: found_user.verified?,
|
108
116
|
jwt: jwt_token(user: found_user)
|
109
117
|
}.to_json
|
data/lib/authify/api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authify-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Gnagy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: authify-core
|
@@ -218,6 +218,20 @@ dependencies:
|
|
218
218
|
- - "~>"
|
219
219
|
- !ruby/object:Gem::Version
|
220
220
|
version: '1.2'
|
221
|
+
- !ruby/object:Gem::Dependency
|
222
|
+
name: liquid
|
223
|
+
requirement: !ruby/object:Gem::Requirement
|
224
|
+
requirements:
|
225
|
+
- - "~>"
|
226
|
+
- !ruby/object:Gem::Version
|
227
|
+
version: '4.0'
|
228
|
+
type: :runtime
|
229
|
+
prerelease: false
|
230
|
+
version_requirements: !ruby/object:Gem::Requirement
|
231
|
+
requirements:
|
232
|
+
- - "~>"
|
233
|
+
- !ruby/object:Gem::Version
|
234
|
+
version: '4.0'
|
221
235
|
- !ruby/object:Gem::Dependency
|
222
236
|
name: bundler
|
223
237
|
requirement: !ruby/object:Gem::Requirement
|
@@ -387,12 +401,19 @@ files:
|
|
387
401
|
- db/migrate/20170208021933_add_admin_to_user.rb
|
388
402
|
- db/migrate/20170208022427_set_default_for_user_admin.rb
|
389
403
|
- db/migrate/20170328151033_add_verified_to_user.rb
|
404
|
+
- db/migrate/20170711151033_add_handle_to_user.rb
|
405
|
+
- db/migrate/20170712101155_add_unique_index_to_groups.rb
|
406
|
+
- db/migrate/20170712101438_add_unique_index_to_identities.rb
|
407
|
+
- db/migrate/20170712103319_add_unique_index_to_organizations.rb
|
408
|
+
- db/migrate/20170712103320_add_unique_index_to_users.rb
|
409
|
+
- db/migrate/20170714051226_set_default_handle_on_users.rb
|
390
410
|
- db/schema.rb
|
391
411
|
- lib/authify/api.rb
|
392
412
|
- lib/authify/api/controllers/apikey.rb
|
393
413
|
- lib/authify/api/controllers/group.rb
|
394
414
|
- lib/authify/api/controllers/identity.rb
|
395
415
|
- lib/authify/api/controllers/organization.rb
|
416
|
+
- lib/authify/api/controllers/trusted_delegate.rb
|
396
417
|
- lib/authify/api/controllers/user.rb
|
397
418
|
- lib/authify/api/helpers/api_user.rb
|
398
419
|
- lib/authify/api/helpers/jwt_encryption.rb
|
@@ -411,6 +432,7 @@ files:
|
|
411
432
|
- lib/authify/api/serializers/group_serializer.rb
|
412
433
|
- lib/authify/api/serializers/identity_serializer.rb
|
413
434
|
- lib/authify/api/serializers/organization_serializer.rb
|
435
|
+
- lib/authify/api/serializers/trusted_delegate_serializer.rb
|
414
436
|
- lib/authify/api/serializers/user_serializer.rb
|
415
437
|
- lib/authify/api/service.rb
|
416
438
|
- lib/authify/api/services/api.rb
|