mojo_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 +14 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +58 -0
- data/Rakefile +12 -0
- data/lib/mojo_auth/version.rb +4 -0
- data/lib/mojo_auth.rb +125 -0
- data/mojo-auth.gemspec +32 -0
- data/spec/mojo_auth_spec.rb +136 -0
- data/spec/spec_helper.rb +13 -0
- metadata +216 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 05391a8161fa237e960a39f300e1a6d1672d29fd
|
4
|
+
data.tar.gz: a2f0a74a402dc59e4607ecf25d8ef34dad6275ce
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 09102d044180a4d493e7b17bb1c2b629470b2841304abd29107cf2ebd10ce4a3f6c7908459f4078daf4e15d4f7ddd885960a4ac066ad73222df95ce468614bcf
|
7
|
+
data.tar.gz: b7dd6991b3603f627363f867f3fccf20400ece3d8c2a820cdfd6e3895d20a1e1bfda8d037f57ec44ecc6d6a9c9111d0e89c9895129da0377c1899fbfb7c3380a
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.0.0
|
4
|
+
- 2.1.3
|
5
|
+
- jruby
|
6
|
+
- jruby-head
|
7
|
+
- ruby-head
|
8
|
+
matrix:
|
9
|
+
include:
|
10
|
+
- rvm: jruby
|
11
|
+
env: JRUBY_OPTS="--2.0"
|
12
|
+
allow_failures:
|
13
|
+
- rvm: jruby
|
14
|
+
before_script:
|
15
|
+
- sudo rm /dev/random
|
16
|
+
- sudo ln -s /dev/urandom /dev/random
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
guard :rubocop do
|
2
|
+
watch(/.+\.rb$/)
|
3
|
+
watch(/(?:.+\/)?\.rubocop\.yml$/) { |m| File.dirname(m[0]) }
|
4
|
+
end
|
5
|
+
|
6
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
7
|
+
watch(/^spec\/.+_spec\.rb$/)
|
8
|
+
watch(/^lib\/(.+)\.rb$/) { |m| "spec/#{m[1]}_spec.rb" }
|
9
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
10
|
+
end
|
11
|
+
|
12
|
+
guard 'yard' do
|
13
|
+
watch(/lib\/.+\.rb/)
|
14
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Mojo Lingo LLC
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
[](https://rubygems.org/gems/mojo_auth)
|
2
|
+
[](http://travis-ci.org/mojolingo/mojo-auth.rb)
|
3
|
+
[](https://gemnasium.com/mojolingo/mojo-auth.rb)
|
4
|
+
[](https://codeclimate.com/github/mojolingo/mojo-auth.rb)
|
5
|
+
[](https://coveralls.io/r/mojolingo/mojo-auth.rb)
|
6
|
+
[](http://inch-ci.org/github/mojolingo/mojo-auth.rb)
|
7
|
+
|
8
|
+
# mojo_auth
|
9
|
+
|
10
|
+
[MojoAuth](http://mojolingo.com/mojoauth) is a set of standard approaches to cross-app authentication based on [Hash-based Message Authentication Codes](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) (HMAC), inspired by ["A REST API For Access To TURN Services"](http://tools.ietf.org/html/draft-uberti-behave-turn-rest).
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'mojo_auth'
|
18
|
+
```
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
$ gem install mojo_auth
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'mojo_auth'
|
32
|
+
|
33
|
+
# Generate a shared secret
|
34
|
+
secret = MojoAuth.create_secret
|
35
|
+
# => "XyD+xeJHivzbOUe3vwdU6Z5vDe/vio34MxKX8HYViR0+p4t/NzaIpbK+9VwX\n5qHCj7m4f7UNRXgOJPXzn6MT0Q==\n"
|
36
|
+
|
37
|
+
# Create temporary credentials
|
38
|
+
credentials = MojoAuth.create_credentials(id: 'foobar', secret: secret)
|
39
|
+
# => {:username=>"1411837760:foobar", :password=>"wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}
|
40
|
+
|
41
|
+
# Test credentials
|
42
|
+
MojoAuth.test_credentials({username: "1411837760:foobar", password: "wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}, secret: secret)
|
43
|
+
# => "foobar"
|
44
|
+
MojoAuth.test_credentials({username: "1411837760:foobar", password: "wrongpassword"}, secret: secret)
|
45
|
+
# => false
|
46
|
+
|
47
|
+
# 1 day later
|
48
|
+
MojoAuth.test_credentials({username: "1411837760:foobar", password: "wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}, secret: secret)
|
49
|
+
# => false
|
50
|
+
```
|
51
|
+
|
52
|
+
## Contributing
|
53
|
+
|
54
|
+
1. [Fork it](https://github.com/mojolingo/mojo_auth.rb/fork)
|
55
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
56
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
57
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
58
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/mojo_auth.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'digest'
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
require 'mojo_auth/version'
|
6
|
+
|
7
|
+
# MojoAuth is a set of standard approaches to cross-app authentication based on HMAC
|
8
|
+
#
|
9
|
+
# @example Typical usage
|
10
|
+
# require 'mojo_auth'
|
11
|
+
#
|
12
|
+
# # Generate a shared secret
|
13
|
+
# secret = MojoAuth.create_secret
|
14
|
+
# # => "XyD+xeJHivzbOUe3vwdU6Z5vDe/vio34MxKX8HYViR0+p4t/NzaIpbK+9VwX\n5qHCj7m4f7UNRXgOJPXzn6MT0Q==\n"
|
15
|
+
#
|
16
|
+
# # Create temporary credentials
|
17
|
+
# credentials = MojoAuth.create_credentials(id: 'foobar', secret: secret)
|
18
|
+
# # => {:username=>"1411837760:foobar", :password=>"wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}
|
19
|
+
#
|
20
|
+
# # Test credentials
|
21
|
+
# MojoAuth.test_credentials({username: "1411837760:foobar", password: "wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}, secret: secret)
|
22
|
+
# # => "foobar"
|
23
|
+
# MojoAuth.test_credentials({username: "1411837760:foobar", password: "wrongpassword"}, secret: secret)
|
24
|
+
# # => false
|
25
|
+
#
|
26
|
+
# # 1 day later
|
27
|
+
# MojoAuth.test_credentials({username: "1411837760:foobar", password: "wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}, secret: secret)
|
28
|
+
# # => false
|
29
|
+
#
|
30
|
+
class MojoAuth
|
31
|
+
DAY_IN_SECONDS = 86_400
|
32
|
+
|
33
|
+
# Create a new random secret
|
34
|
+
#
|
35
|
+
# @return [String] a new secret based on /dev/random
|
36
|
+
def self.create_secret
|
37
|
+
random = File.read('/dev/random', 512)
|
38
|
+
Base64.encode64(Digest::SHA2.new(512).digest(random))
|
39
|
+
end
|
40
|
+
|
41
|
+
# Create a new credential set
|
42
|
+
#
|
43
|
+
# @param [String] id the identity to be asserted in the credentials
|
44
|
+
# @param [String] secret the shared secret with which to create credentials
|
45
|
+
# @param [Integer] ttl the duration for which the credentials should be valid in seconds
|
46
|
+
#
|
47
|
+
# @return [Hash] signed credentials, keys :username and :password
|
48
|
+
#
|
49
|
+
# @example Basic usage
|
50
|
+
# credentials = MojoAuth.create_credentials(secret: secret)
|
51
|
+
# # => {:username=>"1411837760", :password=>"wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}
|
52
|
+
#
|
53
|
+
# @example Asserting an identity
|
54
|
+
# credentials = MojoAuth.create_credentials(id: 'foobar', secret: secret)
|
55
|
+
# # => {:username=>"1411837760:foobar", :password=>"wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}
|
56
|
+
#
|
57
|
+
# @example Specifying an alternative TTL
|
58
|
+
# credentials = MojoAuth.create_credentials(ttl: 600, secret: secret)
|
59
|
+
# # => {:username=>"1411837760", :password=>"wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}
|
60
|
+
#
|
61
|
+
def self.create_credentials(id: nil, secret: required, ttl: DAY_IN_SECONDS)
|
62
|
+
expiry_timestamp = (Time.now.utc + ttl).to_i
|
63
|
+
username = [expiry_timestamp, id].join(':')
|
64
|
+
{ username: username, password: new(secret).sign(username) }
|
65
|
+
end
|
66
|
+
|
67
|
+
# Test that credentials are valid
|
68
|
+
#
|
69
|
+
# @param [Hash] credentials a set of credentials including a :username and a :password
|
70
|
+
# @param [String] secret the shared secret against which to test credentials
|
71
|
+
#
|
72
|
+
# @return [Boolean, String] whether or not the credentials are valid (were created using the specified secret) and current (have not yet expired). When the credentials assert an identity, that identity is returned.
|
73
|
+
#
|
74
|
+
# @example Testing correct credentials
|
75
|
+
# MojoAuth.test_credentials({username: "1411837760", password: "wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}, secret: secret)
|
76
|
+
# # => true
|
77
|
+
#
|
78
|
+
# @example Testing correct ID-asserting credentials
|
79
|
+
# MojoAuth.test_credentials({username: "1411837760:foobar", password: "wb6KxLj6NXcUaqNb1SlHH1V3QHw=\n"}, secret: secret)
|
80
|
+
# # => "foobar"
|
81
|
+
#
|
82
|
+
# @example Testing incorrect credentials
|
83
|
+
# MojoAuth.test_credentials({username: "1411837760:foobar", password: "wrongpassword"}, secret: secret)
|
84
|
+
# # => false
|
85
|
+
#
|
86
|
+
def self.test_credentials(credentials, secret: required)
|
87
|
+
new(secret).assert(credentials)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Work-around for required named parameters pre Ruby 2.1
|
91
|
+
# @private
|
92
|
+
def self.required
|
93
|
+
method = caller_locations(1, 1)[0].label
|
94
|
+
fail ArgumentError, "A required keyword argument was not specified when calling '#{method}'"
|
95
|
+
end
|
96
|
+
|
97
|
+
# Create a MojoAuth instance
|
98
|
+
#
|
99
|
+
# @param [String] secret the shared secret to sign credentials with
|
100
|
+
def initialize(secret)
|
101
|
+
@secret = secret
|
102
|
+
end
|
103
|
+
|
104
|
+
# Sign a message via HMAC-SHA1
|
105
|
+
#
|
106
|
+
# @param [String] message the message to be signed
|
107
|
+
#
|
108
|
+
# @return [String] the message signed with the shared secret
|
109
|
+
def sign(message)
|
110
|
+
Base64.encode64(OpenSSL::HMAC.digest('sha1', @secret, message))
|
111
|
+
end
|
112
|
+
|
113
|
+
# Assert a set of credentials
|
114
|
+
#
|
115
|
+
# @param [Hash] credentials a set of credentials including a :username and a :password
|
116
|
+
# @param [String] secret the shared secret against which to test credentials
|
117
|
+
#
|
118
|
+
# @return [Boolean, String] whether or not the credentials are valid (were created using the specified secret) and current (have not yet expired). When the credentials assert an identity, that identity is returned.
|
119
|
+
def assert(credentials)
|
120
|
+
expiry_timestamp, id = credentials[:username].split(':')
|
121
|
+
return false if expiry_timestamp.to_i < Time.now.utc.to_i
|
122
|
+
return false unless sign(credentials[:username]) == credentials[:password]
|
123
|
+
id || true
|
124
|
+
end
|
125
|
+
end
|
data/mojo-auth.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mojo_auth/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'mojo_auth'
|
8
|
+
spec.version = MojoAuth::VERSION
|
9
|
+
spec.authors = ['Ben Langfeld']
|
10
|
+
spec.email = ['ben@langfeld.me']
|
11
|
+
spec.summary = 'Implementation of MojoAuth in Ruby'
|
12
|
+
spec.description = 'MojoAuth is a set of standard approaches to cross-app authentication based on HMAC.'
|
13
|
+
spec.homepage = 'https://github.com/mojolingo/mojo_auth.rb'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'guard', '~> 2.6'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
25
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.3'
|
26
|
+
spec.add_development_dependency 'rubocop'
|
27
|
+
spec.add_development_dependency 'guard-rubocop', '~> 1.1'
|
28
|
+
spec.add_development_dependency 'coveralls'
|
29
|
+
spec.add_development_dependency 'timecop', '~> 0.7'
|
30
|
+
spec.add_development_dependency 'yard'
|
31
|
+
spec.add_development_dependency 'guard-yard'
|
32
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MojoAuth do
|
4
|
+
describe 'create a secret' do
|
5
|
+
subject(:secret) { described_class.create_secret }
|
6
|
+
|
7
|
+
it { should be_a String }
|
8
|
+
|
9
|
+
it 'should be long enough' do
|
10
|
+
expect(secret.length).to be > 20
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'creating and testing credentials' do
|
15
|
+
let(:secret) { described_class.create_secret }
|
16
|
+
|
17
|
+
it 'raises if the secret is not provided' do
|
18
|
+
expect { described_class.create_credentials }.to raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'without an asserted ID' do
|
22
|
+
let(:credentials) { described_class.create_credentials(secret: secret) }
|
23
|
+
|
24
|
+
describe 'for the generated credentials' do
|
25
|
+
it 'tests true' do
|
26
|
+
expect(described_class.test_credentials(credentials, secret: secret)).to be true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'with an incorrect password' do
|
31
|
+
it 'tests false' do
|
32
|
+
expect(described_class.test_credentials({ username: credentials[:username], password: 'foobar' }, secret: secret)).to be false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'with a different secret' do
|
37
|
+
it 'tests false' do
|
38
|
+
expect(described_class.test_credentials(credentials, secret: 'something_else')).to be false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'when attempting to extend the expiration' do
|
43
|
+
it 'tests false' do
|
44
|
+
expect(described_class.test_credentials({ username: "#{(Time.now + 100_000).to_i}", password: credentials[:password] }, secret: secret)).to be false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'after the default TTL (1 day) expires' do
|
49
|
+
around do |example|
|
50
|
+
credentials # Create the credentials before advancing the time
|
51
|
+
Timecop.freeze(Time.now + MojoAuth::DAY_IN_SECONDS + 1) do
|
52
|
+
example.run
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'tests false' do
|
57
|
+
expect(described_class.test_credentials(credentials, secret: secret)).to be false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'after expiry of a custom TTL' do
|
62
|
+
let(:ttl) { 200 }
|
63
|
+
let(:credentials) { described_class.create_credentials(secret: secret, ttl: ttl) }
|
64
|
+
|
65
|
+
around do |example|
|
66
|
+
credentials # Create the credentials before advancing the time
|
67
|
+
Timecop.freeze(Time.now + ttl + 1) do
|
68
|
+
example.run
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'tests false' do
|
73
|
+
expect(described_class.test_credentials(credentials, secret: secret)).to be false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with an asserted ID' do
|
79
|
+
let(:id) { SecureRandom.uuid }
|
80
|
+
let(:credentials) { described_class.create_credentials(id: id, secret: secret) }
|
81
|
+
|
82
|
+
describe 'for the generated credentials' do
|
83
|
+
it 'tests truthy, returning the asserted ID' do
|
84
|
+
expect(described_class.test_credentials(credentials, secret: secret)).to eql(id)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'with an incorrect password' do
|
89
|
+
it 'tests false' do
|
90
|
+
expect(described_class.test_credentials({ username: credentials[:username], password: 'foobar' }, secret: secret)).to be false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'with a different secret' do
|
95
|
+
it 'tests false' do
|
96
|
+
expect(described_class.test_credentials(credentials, secret: 'something_else')).to be false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'when attempting to extend the expiration' do
|
101
|
+
it 'tests false' do
|
102
|
+
expect(described_class.test_credentials({ username: "#{(Time.now + 100_000).to_i}:#{id}", password: credentials[:password] }, secret: secret)).to be false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'after the default TTL (1 day) expires' do
|
107
|
+
around do |example|
|
108
|
+
credentials # Create the credentials before advancing the time
|
109
|
+
Timecop.freeze(Time.now + MojoAuth::DAY_IN_SECONDS + 1) do
|
110
|
+
example.run
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'tests false' do
|
115
|
+
expect(described_class.test_credentials(credentials, secret: secret)).to be false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe 'after expiry of a custom TTL' do
|
120
|
+
let(:ttl) { 200 }
|
121
|
+
let(:credentials) { described_class.create_credentials(id: id, secret: secret, ttl: ttl) }
|
122
|
+
|
123
|
+
around do |example|
|
124
|
+
credentials # Create the credentials before advancing the time
|
125
|
+
Timecop.freeze(Time.now + ttl + 1) do
|
126
|
+
example.run
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'tests false' do
|
131
|
+
expect(described_class.test_credentials(credentials, secret: secret)).to be false
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mojo_auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Langfeld
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-26 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.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
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: guard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.6'
|
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: guard-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.1'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: coveralls
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: timecop
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.7'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.7'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: yard
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: guard-yard
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description: MojoAuth is a set of standard approaches to cross-app authentication
|
168
|
+
based on HMAC.
|
169
|
+
email:
|
170
|
+
- ben@langfeld.me
|
171
|
+
executables: []
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- ".gitignore"
|
176
|
+
- ".rubocop.yml"
|
177
|
+
- ".travis.yml"
|
178
|
+
- CHANGELOG.md
|
179
|
+
- Gemfile
|
180
|
+
- Guardfile
|
181
|
+
- LICENSE.txt
|
182
|
+
- README.md
|
183
|
+
- Rakefile
|
184
|
+
- lib/mojo_auth.rb
|
185
|
+
- lib/mojo_auth/version.rb
|
186
|
+
- mojo-auth.gemspec
|
187
|
+
- spec/mojo_auth_spec.rb
|
188
|
+
- spec/spec_helper.rb
|
189
|
+
homepage: https://github.com/mojolingo/mojo_auth.rb
|
190
|
+
licenses:
|
191
|
+
- MIT
|
192
|
+
metadata: {}
|
193
|
+
post_install_message:
|
194
|
+
rdoc_options: []
|
195
|
+
require_paths:
|
196
|
+
- lib
|
197
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
|
+
requirements:
|
204
|
+
- - ">="
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
requirements: []
|
208
|
+
rubyforge_project:
|
209
|
+
rubygems_version: 2.2.2
|
210
|
+
signing_key:
|
211
|
+
specification_version: 4
|
212
|
+
summary: Implementation of MojoAuth in Ruby
|
213
|
+
test_files:
|
214
|
+
- spec/mojo_auth_spec.rb
|
215
|
+
- spec/spec_helper.rb
|
216
|
+
has_rdoc:
|