authify-api 0.3.1 → 0.3.2
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/README.md +1 -1
- data/authify-api.gemspec +1 -0
- data/config.ru +2 -1
- data/lib/authify/api.rb +4 -0
- data/lib/authify/api/metrics.rb +55 -0
- data/lib/authify/api/middleware/metrics.rb +34 -0
- data/lib/authify/api/services/api.rb +3 -1
- data/lib/authify/api/services/jwt_provider.rb +30 -0
- data/lib/authify/api/services/monitoring.rb +60 -0
- data/lib/authify/api/services/registration.rb +29 -0
- data/lib/authify/api/version.rb +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 034407bd9058f89a81db15e6d658f16f5d5a5365
|
4
|
+
data.tar.gz: af8a965cc5f481ba754ccd2c5fe79168e35daf68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fb4dd7817c46abf6dc0a2342b48281a9f1862123e990f7c9f4af11baa6d408533fad7376eca7740f3fff865c6052ef63efc88f5b4059abdeb0b8c04f25a8375
|
7
|
+
data.tar.gz: ffafbf61deae31c0ae88c4d8d1333fca27464fd557b5876ddab461304f5fe50a84b31a645da7b948ba55925f9e43a0ce213a0957c77e08542b7e785455f81eb1
|
data/README.md
CHANGED
@@ -83,7 +83,7 @@ File.write(File.expand_path('/path/to/keys/private.pem'), secret_key.to_pem)
|
|
83
83
|
public_key = secret_key
|
84
84
|
public_key.private_key = nil
|
85
85
|
# write out the public key to a file...
|
86
|
-
File.write(File.expand_path('/path/to/keys/public.pem'),
|
86
|
+
File.write(File.expand_path('/path/to/keys/public.pem'), public_key.to_pem)
|
87
87
|
```
|
88
88
|
|
89
89
|
Using the OpenSSL CLI tool:
|
data/authify-api.gemspec
CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
# spec.add_runtime_dependency 'sinja', '~> 1.2', '>= 1.2.4'
|
38
38
|
spec.add_runtime_dependency 'puma', '~> 3.7'
|
39
39
|
spec.add_runtime_dependency 'resque', '~> 1.26'
|
40
|
+
spec.add_runtime_dependency 'hitimes', '~> 1.2'
|
40
41
|
|
41
42
|
spec.add_development_dependency 'bundler', '~> 1.12'
|
42
43
|
spec.add_development_dependency 'rake', '~> 10.0'
|
data/config.ru
CHANGED
@@ -7,4 +7,5 @@ use Rack::ShowExceptions
|
|
7
7
|
run Rack::URLMap.new \
|
8
8
|
'/' => Authify::API::Services::API.new,
|
9
9
|
'/jwt' => Authify::API::Services::JWTProvider.new,
|
10
|
-
'/registration' => Authify::API::Services::Registration.new
|
10
|
+
'/registration' => Authify::API::Services::Registration.new,
|
11
|
+
'/monitoring' => Authify::API::Services::Monitoring.new
|
data/lib/authify/api.rb
CHANGED
@@ -12,6 +12,7 @@ require 'tilt/erb'
|
|
12
12
|
require 'connection_pool'
|
13
13
|
require 'moneta'
|
14
14
|
require 'resque'
|
15
|
+
require 'hitimes'
|
15
16
|
|
16
17
|
# Internal Requirements
|
17
18
|
module Authify
|
@@ -53,6 +54,9 @@ require 'authify/api/models/user'
|
|
53
54
|
require 'authify/api/helpers/jwt_encryption'
|
54
55
|
require 'authify/api/helpers/api_user'
|
55
56
|
require 'authify/api/service'
|
57
|
+
require 'authify/api/metrics'
|
58
|
+
require 'authify/api/middleware/metrics'
|
56
59
|
require 'authify/api/services/api'
|
57
60
|
require 'authify/api/services/jwt_provider'
|
58
61
|
require 'authify/api/services/registration'
|
62
|
+
require 'authify/api/services/monitoring'
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Authify
|
2
|
+
module API
|
3
|
+
# A place to store metrics data
|
4
|
+
class Metrics
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
def update(key, value)
|
8
|
+
write_lock do
|
9
|
+
storage[key] = value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def increment(key, change = 1)
|
14
|
+
write_lock do
|
15
|
+
storage.key?(key) ? storage[key] += change : storage[key] = change
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def decrement(key, change = 1)
|
20
|
+
increment(key, -1 * change)
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](key)
|
24
|
+
storage[key]
|
25
|
+
end
|
26
|
+
|
27
|
+
def time(key)
|
28
|
+
timer = storage.key?(key) ? storage[key] : Hitimes::TimedMetric.new(key)
|
29
|
+
result = timer.measure do
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
update(key, timer)
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
def each(&block)
|
37
|
+
storage.each(&block)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def write_lock
|
43
|
+
@wlock ||= Mutex.new
|
44
|
+
@wlock.synchronize do
|
45
|
+
yield
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def storage
|
50
|
+
# While not perfectly thread-safe, this works well enough for Metrics
|
51
|
+
@storage ||= Concurrent::Map.new
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Authify
|
2
|
+
module API
|
3
|
+
module Middleware
|
4
|
+
# A middleware for analytics of rack requests
|
5
|
+
class Metrics
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
@metrics = Authify::API::Metrics.instance
|
9
|
+
@key = 'rack.action.response'
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
status, header, body = @metrics.time(construct_metric_key('time', env)) do
|
14
|
+
@app.call env
|
15
|
+
end
|
16
|
+
|
17
|
+
@metrics.increment construct_metric_key('count', env)
|
18
|
+
|
19
|
+
[status, header, body]
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def construct_metric_key(type, env)
|
25
|
+
path = Rack::Request.new(env)
|
26
|
+
.path.gsub(%r{/([0-9]+)(/?)}, '/:id\2')
|
27
|
+
.gsub(%r{/}, '.')
|
28
|
+
.chomp('.')
|
29
|
+
"#{@key}.#{type}.#{env['REQUEST_METHOD'].downcase}#{path}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -3,6 +3,8 @@ module Authify
|
|
3
3
|
module Services
|
4
4
|
# A Sinatra App specifically for managing JWT tokens
|
5
5
|
class JWTProvider < Service
|
6
|
+
use Authify::API::Middleware::Metrics
|
7
|
+
|
6
8
|
helpers Helpers::APIUser
|
7
9
|
|
8
10
|
configure do
|
@@ -16,6 +18,21 @@ module Authify
|
|
16
18
|
OPTIONS
|
17
19
|
GET
|
18
20
|
POST
|
21
|
+
],
|
22
|
+
'Access-Control-Allow-Headers' => %w[
|
23
|
+
Origin
|
24
|
+
Accept
|
25
|
+
Accept-Encoding
|
26
|
+
Accept-Language
|
27
|
+
Access-Control-Request-Headers
|
28
|
+
Access-Control-Request-Method
|
29
|
+
Connection
|
30
|
+
Content-Type
|
31
|
+
Host
|
32
|
+
Referer
|
33
|
+
User-Agent
|
34
|
+
X-Requested-With
|
35
|
+
X-Forwarded-For
|
19
36
|
]
|
20
37
|
|
21
38
|
begin
|
@@ -51,12 +68,17 @@ module Authify
|
|
51
68
|
|
52
69
|
if found_user
|
53
70
|
update_current_user found_user
|
71
|
+
Metrics.instance.increment('jwt.tokens.provided')
|
54
72
|
{ jwt: jwt_token(custom_data: custom_data) }.to_json
|
55
73
|
else
|
56
74
|
halt 401
|
57
75
|
end
|
58
76
|
end
|
59
77
|
|
78
|
+
options '/token' do
|
79
|
+
halt 200
|
80
|
+
end
|
81
|
+
|
60
82
|
# Provide information about the JWTs generated by the server
|
61
83
|
get '/meta' do
|
62
84
|
{
|
@@ -66,12 +88,20 @@ module Authify
|
|
66
88
|
}.to_json
|
67
89
|
end
|
68
90
|
|
91
|
+
options '/meta' do
|
92
|
+
halt 200
|
93
|
+
end
|
94
|
+
|
69
95
|
# Provide access to the public ECDSA key
|
70
96
|
get '/key' do
|
71
97
|
{
|
72
98
|
data: public_key.export
|
73
99
|
}.to_json
|
74
100
|
end
|
101
|
+
|
102
|
+
options '/key' do
|
103
|
+
halt 200
|
104
|
+
end
|
75
105
|
end
|
76
106
|
end
|
77
107
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Authify
|
2
|
+
module API
|
3
|
+
module Services
|
4
|
+
# The monitoring application
|
5
|
+
class Monitoring < Service
|
6
|
+
configure do
|
7
|
+
set :protection, except: :http_origin
|
8
|
+
end
|
9
|
+
|
10
|
+
before '*' do
|
11
|
+
content_type 'application/json'
|
12
|
+
headers 'Access-Control-Allow-Origin' => '*',
|
13
|
+
'Access-Control-Allow-Methods' => %w[
|
14
|
+
OPTIONS
|
15
|
+
GET
|
16
|
+
POST
|
17
|
+
],
|
18
|
+
'Access-Control-Allow-Headers' => %w[
|
19
|
+
Origin
|
20
|
+
Accept
|
21
|
+
Accept-Encoding
|
22
|
+
Accept-Language
|
23
|
+
Access-Control-Request-Headers
|
24
|
+
Access-Control-Request-Method
|
25
|
+
Connection
|
26
|
+
Content-Type
|
27
|
+
Host
|
28
|
+
Referer
|
29
|
+
User-Agent
|
30
|
+
X-Requested-With
|
31
|
+
X-Forwarded-For
|
32
|
+
]
|
33
|
+
|
34
|
+
begin
|
35
|
+
unless request.get? || request.options?
|
36
|
+
request.body.rewind
|
37
|
+
@parsed_body = JSON.parse(request.body.read, symbolize_names: true)
|
38
|
+
end
|
39
|
+
rescue => e
|
40
|
+
halt(400, { error: "Request must be valid JSON: #{e.message}" }.to_json)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Provide information about the JWTs generated by the server
|
45
|
+
get '/info' do
|
46
|
+
metrics = Metrics.instance
|
47
|
+
output = {}
|
48
|
+
metrics.each do |key, value|
|
49
|
+
output[key] = value
|
50
|
+
end
|
51
|
+
output.to_json
|
52
|
+
end
|
53
|
+
|
54
|
+
options '/info' do
|
55
|
+
halt 200
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -3,6 +3,7 @@ module Authify
|
|
3
3
|
module Services
|
4
4
|
# A Sinatra App specifically for registering with the system
|
5
5
|
class Registration < Service
|
6
|
+
use Authify::API::Middleware::Metrics
|
6
7
|
helpers Helpers::APIUser
|
7
8
|
|
8
9
|
configure do
|
@@ -16,6 +17,21 @@ module Authify
|
|
16
17
|
OPTIONS
|
17
18
|
GET
|
18
19
|
POST
|
20
|
+
],
|
21
|
+
'Access-Control-Allow-Headers' => %w[
|
22
|
+
Origin
|
23
|
+
Accept
|
24
|
+
Accept-Encoding
|
25
|
+
Accept-Language
|
26
|
+
Access-Control-Request-Headers
|
27
|
+
Access-Control-Request-Method
|
28
|
+
Connection
|
29
|
+
Content-Type
|
30
|
+
Host
|
31
|
+
Referer
|
32
|
+
User-Agent
|
33
|
+
X-Requested-With
|
34
|
+
X-Forwarded-For
|
19
35
|
]
|
20
36
|
|
21
37
|
begin
|
@@ -63,6 +79,10 @@ module Authify
|
|
63
79
|
response.to_json
|
64
80
|
end
|
65
81
|
|
82
|
+
options '/signup' do
|
83
|
+
halt 200
|
84
|
+
end
|
85
|
+
|
66
86
|
post '/forgot_password' do
|
67
87
|
email = @parsed_body[:email]
|
68
88
|
token = @parsed_body[:token]
|
@@ -74,6 +94,7 @@ module Authify
|
|
74
94
|
found_user.verified = true
|
75
95
|
found_user.password = @parsed_body[:password]
|
76
96
|
found_user.save
|
97
|
+
Metrics.instance.increment('registration.password.resets')
|
77
98
|
{
|
78
99
|
id: found_user.id,
|
79
100
|
email: found_user.email,
|
@@ -88,6 +109,10 @@ module Authify
|
|
88
109
|
end
|
89
110
|
end
|
90
111
|
|
112
|
+
options '/forgot_password' do
|
113
|
+
halt 200
|
114
|
+
end
|
115
|
+
|
91
116
|
post '/verify' do
|
92
117
|
email = @parsed_body[:email]
|
93
118
|
password = @parsed_body[:password]
|
@@ -112,6 +137,10 @@ module Authify
|
|
112
137
|
jwt: jwt_token(user: found_user)
|
113
138
|
}.to_json
|
114
139
|
end
|
140
|
+
|
141
|
+
options '/verify' do
|
142
|
+
halt 200
|
143
|
+
end
|
115
144
|
end
|
116
145
|
end
|
117
146
|
end
|
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.3.
|
4
|
+
version: 0.3.2
|
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-05-
|
11
|
+
date: 2017-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: authify-core
|
@@ -204,6 +204,20 @@ dependencies:
|
|
204
204
|
- - "~>"
|
205
205
|
- !ruby/object:Gem::Version
|
206
206
|
version: '1.26'
|
207
|
+
- !ruby/object:Gem::Dependency
|
208
|
+
name: hitimes
|
209
|
+
requirement: !ruby/object:Gem::Requirement
|
210
|
+
requirements:
|
211
|
+
- - "~>"
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: '1.2'
|
214
|
+
type: :runtime
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
requirements:
|
218
|
+
- - "~>"
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: '1.2'
|
207
221
|
- !ruby/object:Gem::Dependency
|
208
222
|
name: bundler
|
209
223
|
requirement: !ruby/object:Gem::Requirement
|
@@ -355,6 +369,8 @@ files:
|
|
355
369
|
- lib/authify/api/helpers/api_user.rb
|
356
370
|
- lib/authify/api/helpers/jwt_encryption.rb
|
357
371
|
- lib/authify/api/jsonapi_utils.rb
|
372
|
+
- lib/authify/api/metrics.rb
|
373
|
+
- lib/authify/api/middleware/metrics.rb
|
358
374
|
- lib/authify/api/models/apikey.rb
|
359
375
|
- lib/authify/api/models/group.rb
|
360
376
|
- lib/authify/api/models/identity.rb
|
@@ -370,6 +386,7 @@ files:
|
|
370
386
|
- lib/authify/api/service.rb
|
371
387
|
- lib/authify/api/services/api.rb
|
372
388
|
- lib/authify/api/services/jwt_provider.rb
|
389
|
+
- lib/authify/api/services/monitoring.rb
|
373
390
|
- lib/authify/api/services/registration.rb
|
374
391
|
- lib/authify/api/version.rb
|
375
392
|
homepage: https://github.com/knuedge/authify-api
|