oauth2_hmac_rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4bd7cd3a18431250766d52ff1e3ba568d9c594f1
4
+ data.tar.gz: 4090b3dc9fda27742c250af149b2cf480471810f
5
+ SHA512:
6
+ metadata.gz: b46700be8f8a16574b4c747ef90da88b8fc1d094af3dd757845bbb8b9ef11016d59d62e1baef5b0f206effb91d7a9eb57b41f94f1b03ef318d50bf5ca0752b5e
7
+ data.tar.gz: 42aee3e43862e007050b14da9e75a37caffd7e653480583d1dfa44587d0c746789bc91df829c932b6a920dc5462ec3b5af38e5e85fbff747ea176da631b34474
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Mustafa TURAN
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Oauth2HmacRails'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+ load 'rails/tasks/statistics.rake'
20
+
21
+
22
+
23
+ Bundler::GemHelper.install_tasks
24
+
25
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
26
+ load 'rails/tasks/engine.rake'
27
+ require "rspec/core/rake_task"
28
+
@@ -0,0 +1,4 @@
1
+ module Oauth2HmacRails
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,92 @@
1
+ require 'oauth2_hmac_header'
2
+ module Oauth2HmacRails
3
+ module Concerns
4
+ module Helper
5
+ extend ActiveSupport::Concern
6
+ included do
7
+ AUTHORIZATION_DEFAULT_HEADER_KEY = 'Authorization'
8
+
9
+ attr_accessor :client_authorization_header_key
10
+ attr_reader :current_client
11
+
12
+ def client_authorization_header_key
13
+ AUTHORIZATION_DEFAULT_HEADER_KEY
14
+ end
15
+
16
+ def authorize!
17
+ begin
18
+ client_id, ts, nonce, ext, mac = ::Oauth2HmacHeader::AuthorizationHeader.parse(client_authorization_header)
19
+ rescue KeyError => e
20
+ return unauthorized I18n.t("oauth2_hmac_rails.missing_hmac_key", details: e)
21
+ end
22
+
23
+ # get client data
24
+ begin
25
+ @current_client = Client.find(client_id)
26
+ rescue ActiveRecord::RecordNotFound
27
+ return unauthorized I18n.t("oauth2_hmac_rails.client_not_found", client_id: client_id)
28
+ end
29
+
30
+ # validate signature
31
+ begin
32
+ validity_flag = ::Oauth2HmacHeader::AuthorizationHeader.is_valid?(
33
+ mac,
34
+ @current_client.mac_algorithm,
35
+ @current_client.mac_key,
36
+ ts,
37
+ nonce,
38
+ request.method,
39
+ request.path,
40
+ request.host,
41
+ request.port,
42
+ ext
43
+ )
44
+ return unauthorized I18n.t("oauth2_hmac_rails.invalid_signature", mac: mac, client_id: client_id) unless validity_flag
45
+ return unauthorized I18n.t("oauth2_hmac_rails.request_timeout_for_client_signature", mac: mac, client_id: client_id) if (ts.to_i + @current_client.mac_request_expires_in) < Time.now.to_i # request timeout
46
+ rescue
47
+ return unauthorized I18n.t("oauth2_hmac_rails.unauthorized")
48
+ end
49
+
50
+ # add valid request to db for preventing replay attacks and api analytics
51
+ create_mac_request(client_id, ts, nonce, ext, mac)
52
+ end
53
+
54
+ private
55
+
56
+ def client_authorization_header
57
+ request.headers[client_authorization_header_key].to_s
58
+ end
59
+
60
+ def unauthorized(reason)
61
+ logger.info "#{self.class.name} / #{reason}"
62
+ attach_unauthorized_header
63
+ render(json: { error: reason }, status: :unauthorized) and return false
64
+ end
65
+
66
+ def attach_unauthorized_header
67
+ response.headers['WWW-Authenticate'] = 'MAC'
68
+ end
69
+
70
+ def create_mac_request(client_id, ts, nonce, ext, mac)
71
+ begin
72
+ MacRequest.create(
73
+ ip: request.ip,
74
+ method: request.method,
75
+ uri: request.path,
76
+ host: request.host,
77
+ port: request.port,
78
+ client_id: client_id,
79
+ ts: ts,
80
+ nonce: nonce,
81
+ ext: ext.to_s,
82
+ mac: mac,
83
+ uts: Time.now.to_i
84
+ )
85
+ rescue ActiveRecord::RecordNotUnique => e
86
+ return unauthorized I18n.t("oauth2_hmac_rails.replay_attack")
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,9 @@
1
+ require 'attr_encrypted'
2
+
3
+ module Oauth2HmacRails
4
+ class Client < ActiveRecord::Base
5
+ include ::Oauth2HmacRails::Concerns::AutoId
6
+ attr_encrypted :mac_key, key: Rails.application.secrets.secret_key_base, encode: true
7
+ serialize :settings, OpenStruct
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ module Oauth2HmacRails
2
+ module Concerns
3
+ module AutoId
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ self.primary_key = 'id'
8
+
9
+ before_create :generate_id
10
+ def generate_id
11
+ (self.id = SecureRandom.uuid.gsub('-', '')) if self.id.nil?
12
+ end
13
+ end
14
+
15
+ class_methods do
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ module Oauth2HmacRails
2
+ class MacRequest < ActiveRecord::Base
3
+ include ::Oauth2HmacRails::Concerns::AutoId
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ en:
2
+ oauth2_hmac_rails:
3
+ missing_hmac_key: "MISSING_HMAC_KEY: %{details}"
4
+ client_not_found: "CLIENT_NOT_FOUND: %{client_id}"
5
+ invalid_signature: "INVALID_SIGNATURE: %{mac} for client id %{client_id}"
6
+ request_timeout_for_client_signature: "REQUEST_TIMEOUT_FOR_CLIENT_SIGNATURE: #{mac} for client id #{client_id}"
7
+ unauthorized: "UNAUTHORIZED"
8
+ replay_attack: "REPLAY_ATTACK"
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Oauth2HmacRails::Engine.routes.draw do
2
+ end
@@ -0,0 +1,13 @@
1
+ class CreateOauth2HmacRailsClients < ActiveRecord::Migration
2
+ def change
3
+ create_table :oauth2_hmac_rails_clients, id: false do |t|
4
+ t.column :id, 'CHAR(32)'
5
+ t.text :encrypted_mac_key, null: false
6
+ t.string :mac_algorithm, default: 'hmac-sha-256'
7
+ t.integer :mac_request_expires_in, default: 3
8
+ t.text :settings
9
+ t.timestamps null: false
10
+ end
11
+ add_index :oauth2_hmac_rails_clients, :id, unique: true, using: :btree
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ class CreateOauth2HmacRailsMacRequests < ActiveRecord::Migration
2
+ def change
3
+ create_table :oauth2_hmac_rails_mac_requests, id: false do |t|
4
+ t.string :id, 'CHAR(32)' # uuid
5
+ t.column :client_id, 'CHAR(32)' # uuid
6
+ t.string :ip, limit: 64 # client ip
7
+ t.string :method, limit: 8 # get, post, put, etc...
8
+ t.string :uri # request path
9
+ t.string :host, limit: 128 # hostname
10
+ t.string :port, limit: 8 # port
11
+ t.string :ts, null: false, limit: 10 # timestamp
12
+ t.string :nonce, null: false # timestamp + random str
13
+ t.string :ext, default: '', null: false # generally md5(request_body)
14
+ t.string :mac, null: false # mac signature
15
+ t.string :uts, null: false, limit: 10 # created at in unixtime format
16
+ t.string :status, null: true
17
+ end
18
+
19
+ add_index :oauth2_hmac_rails_mac_requests, :id, unique: true, using: :btree
20
+ add_index :oauth2_hmac_rails_mac_requests, :client_id
21
+ add_index :oauth2_hmac_rails_mac_requests, [ :mac, :nonce, :ext ], unique: true
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ require "oauth2_hmac_rails/engine"
2
+
3
+ module Oauth2HmacRails
4
+ end
@@ -0,0 +1,10 @@
1
+ module Oauth2HmacRails
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Oauth2HmacRails
4
+
5
+ config.generators do |g|
6
+ g.test_framework :rspec
7
+ g.fixture_replacement :factory_girl, dir: 'spec/factories'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module Oauth2HmacRails
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :oauth2_hmac_rails do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oauth2_hmac_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mustafa TURAN
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.2.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: oauth2_hmac_header
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: attr_encrypted
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
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: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-rails
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
+ - !ruby/object:Gem::Dependency
84
+ name: factory_girl_rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.0'
97
+ description: Authorization server 'Rails Engine' for Oauth2 HMac Draft 01.
98
+ email:
99
+ - mustafaturan.net@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - MIT-LICENSE
105
+ - Rakefile
106
+ - app/controllers/oauth2_hmac_rails/application_controller.rb
107
+ - app/controllers/oauth2_hmac_rails/concerns/helper.rb
108
+ - app/models/oauth2_hmac_rails/client.rb
109
+ - app/models/oauth2_hmac_rails/concerns/auto_id.rb
110
+ - app/models/oauth2_hmac_rails/mac_request.rb
111
+ - config/locales/en.yml
112
+ - config/routes.rb
113
+ - db/migrate/20151116093517_create_oauth2_hmac_rails_clients.rb
114
+ - db/migrate/20151116093601_create_oauth2_hmac_rails_mac_requests.rb
115
+ - lib/oauth2_hmac_rails.rb
116
+ - lib/oauth2_hmac_rails/engine.rb
117
+ - lib/oauth2_hmac_rails/version.rb
118
+ - lib/tasks/oauth2_hmac_rails_tasks.rake
119
+ homepage: https://github.com/mustafaturan/oauth2_hmac_rails
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.4.5.1
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: Authorization server 'Rails Engine' for Oauth2 HMac Draft 01.
143
+ test_files: []