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.
@@ -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
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -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'
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.2
5
+ before_install: gem install bundler -v 1.13.6
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ source 'https://rubygems.org'
3
+
4
+ # Specify your gem's dependencies in dvelp_api_auth.gemspec
5
+ gemspec
@@ -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.
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task default: :spec
@@ -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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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,6 @@
1
+ # frozen_string_literal: true
2
+ require 'dvelp_api_auth/helper_methods'
3
+ Gem.find_files('dvelp_api_auth/**/*.rb').each { |f| require f }
4
+
5
+ module DvelpApiAuth
6
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ module DvelpApiAuth
3
+ module Authentication
4
+ def valid_request?
5
+ DvelpApiAuth::Authentication::ApiRequest.new(request).valid?
6
+ end
7
+ end
8
+ 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,11 @@
1
+ module DvelpApiAuth
2
+ module HelperMethods
3
+ def present?(instance)
4
+ instance && !instance.to_s.empty?
5
+ end
6
+
7
+ def blank?(instance)
8
+ !present?(instance)
9
+ end
10
+ end
11
+ 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
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ module DvelpApiAuth
3
+ VERSION = '0.1.0'
4
+ 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: []