active_model_otp 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjdjOTMxYzkxNjI1MGM0ODdiZmNkZmFiYTZiMjBlZjc4ZTQzMjg2Mw==
5
+ data.tar.gz: !binary |-
6
+ ZTQ4OGJlNTQzOTViZWEzNDU1MWU1YmQ3Y2Q5Njc3ZDQ0ZjdmMDVkYQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YWIyZDViZGE0YWRhYjc2M2YyZjRkYWVhMDI3NjA4YjgxMzRhY2E1MjNkOWM4
10
+ MmE5YjZlOTlhYmVkMDhkZjNjZjMzOTYzNzkzNTQ0ODZjMGEzOTRjZTc1OGNj
11
+ NDYwNDRiNmEzNmNjZWJhYTQxNzdhNzE2MzBjYzVhNjFhMzAzMWQ=
12
+ data.tar.gz: !binary |-
13
+ YjdkNDlkYmRjNWM1MTRlZDQzZTMwNzFkZGE4OGMwMzU5NmQ1YWExMDY4YTA2
14
+ NTMwOTgwYWE5NjdkM2M1MzdiMDc3MGZhMWM0YWUzMDA2NDFlNDFmNWM3ZTlk
15
+ Y2ViODliODQ4YzQxYmY1Y2UyNWNiYjIzY2QwMDQzZDllNWFhYjQ=
@@ -0,0 +1,9 @@
1
+ #v1.0.0
2
+ - Avoid overriding predefined otp_column value when initializing resource (Ilan Stern) https://github.com/heapsource/active_model_otp/pull/10
3
+ - Pad OTP codes with less than 6 digits (Johan Brissmyr) https://github.com/heapsource/active_model_otp/pull/7
4
+ - Get rid of deprecation warnings in Rails 4.1 (Nick DeMonner)
5
+
6
+ #v0.1.0
7
+ - OTP codes can be in 5 or 6 digits (André Luis Leal Cardoso Junior)
8
+ - Require 'cgi', rotp needs it for encoding parameters (André Luis Leal Cardoso Junior)
9
+ - Change column name for otp secret key (robertomiranda)
data/README.md CHANGED
@@ -37,17 +37,22 @@ class User < ActiveRecord::Base
37
37
  end
38
38
  ```
39
39
 
40
+ Note: If you're adding this to an existing user model you'll need to generate *otp_secret_key* with a migration like:
41
+ ```ruby
42
+ User.all.each { |user| user.update_attribute(:otp_secret_key, ROTP::Base32.random_base32) }
43
+ ```
44
+
40
45
 
41
46
  ##Usage
42
47
 
43
48
  The has_one_time_password sentence provides to the model some useful methods in order to implement our TFA system. AMo:Otp generates one time passwords according to [RFC 4226](http://tools.ietf.org/html/rfc4226) and the [HOTP RFC](http://tools.ietf.org/html/draft-mraihi-totp-timebased-00). This is compatible with Google Authenticator apps available for Android and iPhone, and now in use on GMail.
44
49
 
45
- The otp_secret_key is saved automatically when a object is created,
50
+ The otp_secret_key is saved automatically when a object is created,
46
51
 
47
52
  ```ruby
48
53
  user = User.create(email: "hello@heapsource.com")
49
54
  user.otp_secret_key
50
- => "jt3gdd2qm6su5iqh"
55
+ => "jt3gdd2qm6su5iqh"
51
56
  ```
52
57
 
53
58
  **Note:** You can fork the applications for [iPhone](https://github.com/heapsource/google-authenticator) & [Android](https://github.com/heapsource/google-authenticator.android) and customize it
@@ -57,6 +62,12 @@ user.otp_secret_key
57
62
  user.otp_code # => '186522'
58
63
  sleep 30
59
64
  user.otp_code # => '850738'
65
+
66
+ # Override current time
67
+ user.otp_code(time: Time.now + 3600) # => '317438'
68
+
69
+ # Don't zero-pad to six digits
70
+ user.otp_code(padding: false) # => '438'
60
71
  ```
61
72
 
62
73
  ### Authenticating using a code
@@ -80,11 +91,11 @@ user.authenticate_otp('186522', drift: 60) # => true
80
91
  The library works with the Google Authenticator iPhone and Android app, and also includes the ability to generate provisioning URI's to use with the QR Code scanner built into the app.
81
92
 
82
93
  ```ruby
83
- # Use you user's emails for generate the provision_url
84
- user.provision_uri # => 'otpauth://totp/hello@heapsource.com?secret=2z6hxkdwi3uvrnpn'
94
+ # Use you user's emails for generate the provisioning_url
95
+ user.provisioning_uri # => 'otpauth://totp/hello@heapsource.com?secret=2z6hxkdwi3uvrnpn'
85
96
 
86
- # Use a custom fied for generate the provision_url
87
- user.provision_uri("hello") # => 'otpauth://totp/hello?secret=2z6hxkdwi3uvrnpn'
97
+ # Use a custom fied for generate the provisioning_url
98
+ user.provisioning_uri("hello") # => 'otpauth://totp/hello?secret=2z6hxkdwi3uvrnpn'
88
99
  ```
89
100
 
90
101
  This can then be rendered as a QR Code which can then be scanned and added to the users list of OTP credentials.
@@ -119,13 +130,10 @@ puts "Current code #{user.otp_code}"
119
130
 
120
131
  ### Useful Examples
121
132
 
122
- #### Generating QR Code with Google Charts API
123
-
124
- #### Generating QR Code with rqrcode and chunky_png
125
-
126
- #### Sendind code via email with Twilio
127
-
128
- #### Using with Mongoid
133
+ - [Generate QR code with rqrcode gem](https://github.com/heapsource/active_model_otp/wiki/Generate-QR-code-with-rqrcode-gem)
134
+ - Generating QR Code with Google Charts API
135
+ - [Sendind code via email with Twilio](https://github.com/heapsource/active_model_otp/wiki/Send-code-via-Twilio-SMS)
136
+ - Using with Mongoid
129
137
 
130
138
  ## Contributing
131
139
 
@@ -10,7 +10,7 @@ module ActiveModel
10
10
 
11
11
  include InstanceMethodsOnActivation
12
12
 
13
- before_create { self.otp_column = ROTP::Base32.random_base32 }
13
+ before_create { self.otp_column ||= ROTP::Base32.random_base32 }
14
14
 
15
15
  if respond_to?(:attributes_protected_by_default)
16
16
  def self.attributes_protected_by_default #:nodoc:
@@ -30,8 +30,15 @@ module ActiveModel
30
30
  end
31
31
  end
32
32
 
33
- def otp_code(time = Time.now)
34
- ROTP::TOTP.new(self.otp_column).at(time)
33
+ def otp_code(options = {})
34
+ if options.is_a? Hash
35
+ time = options.fetch(:time, Time.now)
36
+ padding = options.fetch(:padding, true)
37
+ else
38
+ time = options
39
+ padding = true
40
+ end
41
+ ROTP::TOTP.new(self.otp_column).at(time, padding)
35
42
  end
36
43
 
37
44
  def provisioning_uri(account = nil)
@@ -1,5 +1,5 @@
1
1
  module ActiveModel
2
2
  module Otp
3
- VERSION = "0.1.0"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  require "active_model"
2
- require "active_support/core_ext/class/attribute_accessors"
2
+ require "active_support/core_ext/module/attribute_accessors"
3
3
  require "cgi"
4
4
  require "rotp"
5
5
  require "active_model/one_time_password"
@@ -27,8 +27,14 @@ class OtpTest < MiniTest::Unit::TestCase
27
27
  end
28
28
 
29
29
  def test_otp_code
30
- assert_match(/\d{5,6}/, @user.otp_code.to_s)
31
- assert_match(/\d{5,6}/, @visitor.otp_code.to_s)
30
+ assert_match(/^\d{6}$/, @user.otp_code.to_s)
31
+ assert_match(/^\d{6}$/, @visitor.otp_code.to_s)
32
+ end
33
+
34
+ def test_otp_code_padding
35
+ @user.otp_column = 'kw5jhligwqaiw7jc'
36
+ assert_match(/^\d{6}$/, @user.otp_code(time: 2160, padding: true).to_s)
37
+ assert_match(/^\d{3}$/, @user.otp_code(time: 2160, padding: false).to_s)
32
38
  end
33
39
 
34
40
  def test_provisioning_uri_with_provided_account
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_model_otp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Guillermo Iguaran
@@ -11,12 +10,11 @@ authors:
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2013-12-19 00:00:00.000000000 Z
13
+ date: 2014-08-01 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: activemodel
18
17
  requirement: !ruby/object:Gem::Requirement
19
- none: false
20
18
  requirements:
21
19
  - - ! '>='
22
20
  - !ruby/object:Gem::Version
@@ -24,7 +22,6 @@ dependencies:
24
22
  type: :runtime
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
25
  requirements:
29
26
  - - ! '>='
30
27
  - !ruby/object:Gem::Version
@@ -32,7 +29,6 @@ dependencies:
32
29
  - !ruby/object:Gem::Dependency
33
30
  name: rotp
34
31
  requirement: !ruby/object:Gem::Requirement
35
- none: false
36
32
  requirements:
37
33
  - - ! '>='
38
34
  - !ruby/object:Gem::Version
@@ -40,7 +36,6 @@ dependencies:
40
36
  type: :runtime
41
37
  prerelease: false
42
38
  version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
39
  requirements:
45
40
  - - ! '>='
46
41
  - !ruby/object:Gem::Version
@@ -48,7 +43,6 @@ dependencies:
48
43
  - !ruby/object:Gem::Dependency
49
44
  name: bundler
50
45
  requirement: !ruby/object:Gem::Requirement
51
- none: false
52
46
  requirements:
53
47
  - - ~>
54
48
  - !ruby/object:Gem::Version
@@ -56,7 +50,6 @@ dependencies:
56
50
  type: :development
57
51
  prerelease: false
58
52
  version_requirements: !ruby/object:Gem::Requirement
59
- none: false
60
53
  requirements:
61
54
  - - ~>
62
55
  - !ruby/object:Gem::Version
@@ -64,7 +57,6 @@ dependencies:
64
57
  - !ruby/object:Gem::Dependency
65
58
  name: rake
66
59
  requirement: !ruby/object:Gem::Requirement
67
- none: false
68
60
  requirements:
69
61
  - - ! '>='
70
62
  - !ruby/object:Gem::Version
@@ -72,7 +64,6 @@ dependencies:
72
64
  type: :development
73
65
  prerelease: false
74
66
  version_requirements: !ruby/object:Gem::Requirement
75
- none: false
76
67
  requirements:
77
68
  - - ! '>='
78
69
  - !ruby/object:Gem::Version
@@ -80,7 +71,6 @@ dependencies:
80
71
  - !ruby/object:Gem::Dependency
81
72
  name: minitest
82
73
  requirement: !ruby/object:Gem::Requirement
83
- none: false
84
74
  requirements:
85
75
  - - ! '>='
86
76
  - !ruby/object:Gem::Version
@@ -88,7 +78,6 @@ dependencies:
88
78
  type: :development
89
79
  prerelease: false
90
80
  version_requirements: !ruby/object:Gem::Requirement
91
- none: false
92
81
  requirements:
93
82
  - - ! '>='
94
83
  - !ruby/object:Gem::Version
@@ -105,6 +94,7 @@ extra_rdoc_files: []
105
94
  files:
106
95
  - .gitignore
107
96
  - .travis.yml
97
+ - CHANGELOG.md
108
98
  - Gemfile
109
99
  - LICENSE.txt
110
100
  - README.md
@@ -120,27 +110,26 @@ files:
120
110
  homepage: ''
121
111
  licenses:
122
112
  - MIT
113
+ metadata: {}
123
114
  post_install_message:
124
115
  rdoc_options: []
125
116
  require_paths:
126
117
  - lib
127
118
  required_ruby_version: !ruby/object:Gem::Requirement
128
- none: false
129
119
  requirements:
130
120
  - - ! '>='
131
121
  - !ruby/object:Gem::Version
132
122
  version: '0'
133
123
  required_rubygems_version: !ruby/object:Gem::Requirement
134
- none: false
135
124
  requirements:
136
125
  - - ! '>='
137
126
  - !ruby/object:Gem::Version
138
127
  version: '0'
139
128
  requirements: []
140
129
  rubyforge_project:
141
- rubygems_version: 1.8.25
130
+ rubygems_version: 2.2.2
142
131
  signing_key:
143
- specification_version: 3
132
+ specification_version: 4
144
133
  summary: Adds methods to set and authenticate against one time passwords.
145
134
  test_files:
146
135
  - test/models/user.rb