dvelp_api_auth 0.1.0
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +77 -0
- data/.travis.yml +5 -0
- data/Gemfile +5 -0
- data/README.md +37 -0
- data/Rakefile +7 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/dvelp_api_auth.gemspec +34 -0
- data/lib/dvelp_api_auth.rb +6 -0
- data/lib/dvelp_api_auth/authentication.rb +8 -0
- data/lib/dvelp_api_auth/authentication/api_request.rb +61 -0
- data/lib/dvelp_api_auth/authentication/signature.rb +66 -0
- data/lib/dvelp_api_auth/authentication/validator.rb +68 -0
- data/lib/dvelp_api_auth/helper_methods.rb +11 -0
- data/lib/dvelp_api_auth/tests/helpers.rb +30 -0
- data/lib/dvelp_api_auth/version.rb +4 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 503dc12200bdbfde4944ed4eaa69eaf12ca14b1f
|
4
|
+
data.tar.gz: 481956fccaf7b850ae135db41400f0d8de6e822b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1a7ae4632157f1dca253c805c3e1d24b9994f9d332d820941e5ba8beecf1dde7a6a10bedf558ba950eafd994d72f621c003364d48cfebb4f2dc621770ad1c8d6
|
7
|
+
data.tar.gz: f7f2be92e1cf99b0367bc74f33b680660a86e61be6d74dcc04b07cfc104d19d41209271b87021ad673a155d34fcb0a7d24756a7a35b9d4694781811d173b87ff
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3
|
3
|
+
Exclude:
|
4
|
+
- 'spec/dummy/**/*'
|
5
|
+
|
6
|
+
Metrics/LineLength:
|
7
|
+
Max: 80
|
8
|
+
Exclude:
|
9
|
+
- 'db/schema.rb'
|
10
|
+
|
11
|
+
Metrics/MethodLength:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Metrics/BlockLength:
|
15
|
+
Exclude:
|
16
|
+
- './dopay_payment_engine.gemspec'
|
17
|
+
- './spec/**/*'
|
18
|
+
|
19
|
+
Style/AlignParameters:
|
20
|
+
EnforcedStyle: with_fixed_indentation
|
21
|
+
|
22
|
+
Style/BlockComments:
|
23
|
+
Exclude:
|
24
|
+
- 'spec/spec_helper.rb'
|
25
|
+
|
26
|
+
Style/Documentation:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Style/EmptyLinesAroundBlockBody:
|
30
|
+
Exclude:
|
31
|
+
- 'db/schema.rb'
|
32
|
+
|
33
|
+
Style/ExtraSpacing:
|
34
|
+
Exclude:
|
35
|
+
- 'bin/*'
|
36
|
+
- 'db/schema.rb'
|
37
|
+
|
38
|
+
Style/FirstParameterIndentation:
|
39
|
+
EnforcedStyle: consistent
|
40
|
+
|
41
|
+
Style/GuardClause:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
Style/HashSyntax:
|
45
|
+
Exclude:
|
46
|
+
- 'Rakefile'
|
47
|
+
- 'lib/tasks/*.rake'
|
48
|
+
|
49
|
+
Style/IfUnlessModifier:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Style/IndentArray:
|
53
|
+
EnforcedStyle: consistent
|
54
|
+
|
55
|
+
Style/MultilineMethodCallIndentation:
|
56
|
+
EnforcedStyle: indented
|
57
|
+
|
58
|
+
Style/NumericLiterals:
|
59
|
+
Exclude:
|
60
|
+
- 'db/schema.rb'
|
61
|
+
|
62
|
+
Style/PercentLiteralDelimiters:
|
63
|
+
PreferredDelimiters:
|
64
|
+
'%': ()
|
65
|
+
'%i': '[]'
|
66
|
+
'%q': ()
|
67
|
+
'%Q': ()
|
68
|
+
'%r': '{}'
|
69
|
+
'%s': ()
|
70
|
+
'%w': '[]'
|
71
|
+
'%W': '[]'
|
72
|
+
'%x': ()
|
73
|
+
|
74
|
+
Style/StringLiterals:
|
75
|
+
Exclude:
|
76
|
+
- 'bin/*'
|
77
|
+
- 'db/schema.rb'
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# DvelpApiAuth
|
2
|
+
|
3
|
+
This gem provides an ability to auth through api
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'dvelp_api_auth'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install dvelp_api_auth
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
First of all you need to set env variable to encrypt requests:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
ENV['DVELP_API_AUTH_SECRET_KEY'] = 'Some key'
|
27
|
+
```
|
28
|
+
|
29
|
+
## Development
|
30
|
+
|
31
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
32
|
+
|
33
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
34
|
+
|
35
|
+
## Contributing
|
36
|
+
|
37
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/dvelp_api_auth.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'dvelp_api_auth'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'dvelp_api_auth/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'dvelp_api_auth'
|
9
|
+
spec.version = DvelpApiAuth::VERSION
|
10
|
+
spec.authors = ['Egor Vorobiev']
|
11
|
+
spec.email = ['egor@dvelp.co.uk']
|
12
|
+
|
13
|
+
spec.summary = 'It provides auth between bridge and DE apps'
|
14
|
+
|
15
|
+
if spec.respond_to?(:metadata)
|
16
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
17
|
+
else
|
18
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
19
|
+
'public gem pushes.'
|
20
|
+
end
|
21
|
+
|
22
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
23
|
+
f.match(%r{^(test|spec|features)/})
|
24
|
+
end
|
25
|
+
spec.bindir = 'exe'
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
|
29
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
30
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
31
|
+
spec.add_development_dependency 'rubocop'
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
33
|
+
spec.add_development_dependency 'pry'
|
34
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DvelpApiAuth
|
3
|
+
module Authentication
|
4
|
+
class ApiRequest
|
5
|
+
include ::DvelpApiAuth::HelperMethods
|
6
|
+
|
7
|
+
attr_reader :api_request
|
8
|
+
|
9
|
+
def initialize(api_request)
|
10
|
+
@api_request = api_request
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid?
|
14
|
+
DvelpApiAuth::Authentication::Validator.new(
|
15
|
+
client_authorization_code,
|
16
|
+
timestamp,
|
17
|
+
server_signature
|
18
|
+
).authentic?
|
19
|
+
end
|
20
|
+
|
21
|
+
def server_signature
|
22
|
+
DvelpApiAuth::Authentication::Signature.new(
|
23
|
+
fullpath,
|
24
|
+
raw_post,
|
25
|
+
timestamp,
|
26
|
+
multipart?,
|
27
|
+
body
|
28
|
+
).generate
|
29
|
+
end
|
30
|
+
|
31
|
+
def mulipart_server_signature; end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def timestamp
|
36
|
+
api_request.headers.env['HTTP_TIMESTAMP']
|
37
|
+
end
|
38
|
+
|
39
|
+
def raw_post
|
40
|
+
@raw_post ||= api_request.raw_post
|
41
|
+
end
|
42
|
+
|
43
|
+
def fullpath
|
44
|
+
@full_path ||= api_request.fullpath
|
45
|
+
end
|
46
|
+
|
47
|
+
def body
|
48
|
+
@body ||= api_request.body
|
49
|
+
end
|
50
|
+
|
51
|
+
def multipart?
|
52
|
+
present?(api_request.headers['Content-Type']) &&
|
53
|
+
api_request.headers['Content-Type'].try(:include?, 'multipart')
|
54
|
+
end
|
55
|
+
|
56
|
+
def client_authorization_code
|
57
|
+
api_request.headers.env['HTTP_AUTHORISATION']
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module DvelpApiAuth
|
5
|
+
module Authentication
|
6
|
+
class Signature
|
7
|
+
include ::DvelpApiAuth::HelperMethods
|
8
|
+
|
9
|
+
attr_accessor :raw_post, :request_timestamp, :body, :multipart
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
fullpath, raw_post, request_timestamp, multipart = false, body = nil
|
13
|
+
)
|
14
|
+
@fullpath = fullpath
|
15
|
+
@raw_post = raw_post
|
16
|
+
@request_timestamp = request_timestamp
|
17
|
+
@multipart = multipart
|
18
|
+
@body = body
|
19
|
+
|
20
|
+
unless present?(@request_timestamp)
|
21
|
+
raise 'Request full_path is required'
|
22
|
+
end
|
23
|
+
raise 'Timestamp is required' unless present?(@request_timestamp)
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate
|
27
|
+
string = multipart? ? multipart_key : timesensitive_string_to_sign
|
28
|
+
|
29
|
+
OpenSSL::HMAC.hexdigest(
|
30
|
+
OpenSSL::Digest.new('SHA256'),
|
31
|
+
app_secret_key,
|
32
|
+
string
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def fullpath
|
37
|
+
@fullpath.split('?')[0]
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def timesensitive_string_to_sign
|
43
|
+
request_timestamp.to_s + string_to_sign
|
44
|
+
end
|
45
|
+
|
46
|
+
def multipart_key
|
47
|
+
request_timestamp.to_s +
|
48
|
+
Base64.strict_encode64(fullpath).chomp +
|
49
|
+
body.length.to_s
|
50
|
+
end
|
51
|
+
|
52
|
+
def string_to_sign
|
53
|
+
string = blank?(raw_post) ? fullpath : raw_post
|
54
|
+
Base64.strict_encode64(string).chomp
|
55
|
+
end
|
56
|
+
|
57
|
+
def app_secret_key
|
58
|
+
ENV['DVELP_API_AUTH_SECRET_KEY']
|
59
|
+
end
|
60
|
+
|
61
|
+
def multipart?
|
62
|
+
@multipart
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DvelpApiAuth
|
3
|
+
module Authentication
|
4
|
+
class Validator
|
5
|
+
include ::DvelpApiAuth::HelperMethods
|
6
|
+
|
7
|
+
attr_reader :client_authorization_code, :server_signature
|
8
|
+
|
9
|
+
def initialize(
|
10
|
+
client_authorization_code,
|
11
|
+
request_timestamp,
|
12
|
+
server_signature
|
13
|
+
)
|
14
|
+
@client_authorization_code = client_authorization_code
|
15
|
+
@request_timestamp = request_timestamp
|
16
|
+
@server_signature = server_signature
|
17
|
+
|
18
|
+
unless present?(@client_authorization_code)
|
19
|
+
raise 'Client authorization code is required'
|
20
|
+
end
|
21
|
+
unless present?(@server_signature)
|
22
|
+
raise 'Server signature is required'
|
23
|
+
end
|
24
|
+
unless present?(@request_timestamp)
|
25
|
+
raise 'Timestamp is required'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def authentic?
|
30
|
+
valid_signature? && valid_timestamp?
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def valid_timestamp?
|
36
|
+
request_timestamp.between?(time_validity_start, time_validity_end)
|
37
|
+
end
|
38
|
+
|
39
|
+
def valid_signature?
|
40
|
+
client_signature_digest == server_signature_digest
|
41
|
+
end
|
42
|
+
|
43
|
+
def client_signature_digest
|
44
|
+
Digest::SHA1.hexdigest(client_authorization_code)
|
45
|
+
end
|
46
|
+
|
47
|
+
def server_signature_digest
|
48
|
+
Digest::SHA1.hexdigest(server_signature)
|
49
|
+
end
|
50
|
+
|
51
|
+
def time_validity_start
|
52
|
+
@time_validity_start ||= (time_benchmark - 15 * 60).to_i
|
53
|
+
end
|
54
|
+
|
55
|
+
def time_validity_end
|
56
|
+
@time_validity_end ||= (time_benchmark + 5 * 60).to_i
|
57
|
+
end
|
58
|
+
|
59
|
+
def time_benchmark
|
60
|
+
@time_benchmark ||= Time.now.utc
|
61
|
+
end
|
62
|
+
|
63
|
+
def request_timestamp
|
64
|
+
@request_timestamp.to_i
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DvelpApiAuth
|
2
|
+
module Tests
|
3
|
+
module Helpers
|
4
|
+
def authorize!(fullpath, request_params = {})
|
5
|
+
set_authorisation_header(fullpath, request_params)
|
6
|
+
set_timestamp
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def set_authorisation_header(fullpath, request_params)
|
12
|
+
if request_params.present? && request_params.is_a?(Hash)
|
13
|
+
raw_post = request_params.to_query
|
14
|
+
end
|
15
|
+
|
16
|
+
http_auth = DvelpApiAuth::Authentication::Signature.new(
|
17
|
+
fullpath,
|
18
|
+
raw_post,
|
19
|
+
Time.current
|
20
|
+
).generate
|
21
|
+
|
22
|
+
request.env['HTTP_AUTHORISATION'] = http_auth
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_timestamp
|
26
|
+
request.env['HTTP_TIMESTAMP'] = Time.current
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dvelp_api_auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Egor Vorobiev
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- egor@dvelp.co.uk
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".rubocop.yml"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- bin/console
|
98
|
+
- bin/setup
|
99
|
+
- dvelp_api_auth.gemspec
|
100
|
+
- lib/dvelp_api_auth.rb
|
101
|
+
- lib/dvelp_api_auth/authentication.rb
|
102
|
+
- lib/dvelp_api_auth/authentication/api_request.rb
|
103
|
+
- lib/dvelp_api_auth/authentication/signature.rb
|
104
|
+
- lib/dvelp_api_auth/authentication/validator.rb
|
105
|
+
- lib/dvelp_api_auth/helper_methods.rb
|
106
|
+
- lib/dvelp_api_auth/tests/helpers.rb
|
107
|
+
- lib/dvelp_api_auth/version.rb
|
108
|
+
homepage:
|
109
|
+
licenses: []
|
110
|
+
metadata:
|
111
|
+
allowed_push_host: https://rubygems.org
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options: []
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 2.5.2
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: It provides auth between bridge and DE apps
|
132
|
+
test_files: []
|