truefactor 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d72749bf6d165774fc2a29843be94b61ac35b322
4
- data.tar.gz: 88e23b243b8d1778b3aed687a497b392e8e5321c
3
+ metadata.gz: 752e556f5ec6e34c45183fd30c2a00ccf4f0d13b
4
+ data.tar.gz: 5caacd440e0fff84712664632f4fd5882deb2bcb
5
5
  SHA512:
6
- metadata.gz: 7fda1eaeea85d3c40cc0d0923a3b677141b8912a17ce00734c562b15e96e414778c9ac111e72ff526720c493dc8b718877951eea6b8e9220dd39ac05575064a0
7
- data.tar.gz: 62546f537cea77c609e95372c7c1493d5cebaf1eee48c2836da56e32fa88543164408a5e9c3a31e3838d2e33b3ff334294e9d21ba621230c4e19689152aaf58a
6
+ metadata.gz: d0bd77db83c188d07278161f54ce13c2673ecd882b2dfb48b62ec38920fe468fd3a1a800cc9c83bac3c83b1dcd17df3e7831a69baeb131b08d488857b334a896
7
+ data.tar.gz: 1fdb77c038e236b935eee9b7f3df40806879d0dd87e5008a1771340573a8678c4b742c279260de3622c54f11373b931fe8d9eb67152c9dfb08e0ad8712a631e0
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .DS_Store
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ logfile
20
+ gemfiles/*.gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in truefactor.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Alexander Yunin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,97 @@
1
+ # Installation
2
+
3
+ Truefactor.io can be your only authentication option or you can add it to existing auth schemes such as devise, authlogic etc. The installation takes up to 5 minutes. <a href="http://cobased.com/">Check out the demo how it looks like.</a> Also you can take a look at another <a href="https://thawing-falls-18565.herokuapp.com/"demo</a> with a github <a href="https://github.com/avyy/truefactor-bankapp">repo</a>.
4
+
5
+
6
+ ```
7
+ # (starting from scratch?) email field is required and used as identifier (tfid)
8
+ rails new bankapp
9
+ rails g model User email:string
10
+
11
+ # add to Gemfile (use edge version for now)
12
+ gem 'truefactor', github: 'sakurity/truefactory-ruby'
13
+
14
+ # run a generator to install it
15
+ rails g truefactor:install User
16
+
17
+ # Final touch! Put this anywhere in views to let users sign in and sign up with one button
18
+ <%= link_to_truefactor %>
19
+
20
+ # Or something like:
21
+ link_to 'Sign in', truefactor_path
22
+ ```
23
+
24
+
25
+ (optional) add your app description and icon to generated /config/initializers/truefactor.rb
26
+ ```
27
+ Truefactor.configure do |c|
28
+ c.origin_name = "Cobased - import your trips"
29
+ c.icon = "" #must be https
30
+ c.tfid_type = :username #email by default
31
+ end
32
+ ```
33
+
34
+ This is it! Other features (verified requests/responses/paired devices) are optional and mostly useful for very sensitive applications. Pull requests on how to simplify the installation are welcome.
35
+
36
+ If you have any *critical actions* in your app: money transfer, destroying a repo or showing an API key, you can protect them from XSS/extensions/widgets and even device compromise with *Verified Requests*. Just add Truefactor JS SDK:
37
+ ```
38
+ <script src="https://truefactor.io/sdk.js"></script>
39
+ <% if current_user %>
40
+ <script>Truefactor.tfid = <%=raw current_user.email.to_json %>;</script>
41
+ <% end %>
42
+ ```
43
+ On the client side you need to get signatures first. You have form like this:
44
+ ```
45
+ <form action="/btcsend" id="withdraw_form">
46
+ Amount: <input id="amount" name="amount" value="1.123"><br>
47
+ Address: <input id="addr" name="addr" value="1JU9gCtodk9rc2s4x85zDWYUo38gVSUaaH"><br>
48
+ <br>
49
+ <a id="withdraw_button"><img width="180px" src="<%=truefactor_domain%>/approve.png"/></a>
50
+ ```
51
+
52
+ Add onclick event to the button
53
+ ```
54
+ Truefactor.origin_name = 'Cobased';
55
+ Truefactor.icon = 'http://photos.state.gov/libraries/media/788/images/90x90.gif';
56
+
57
+ $('#withdraw_button').click(function(){
58
+ var challenge = "Send " + $('#amount').val() + " btc to " + $('#addr').val() + "?";
59
+ Truefactor.sign(challenge, function(signs){
60
+ $('#withdraw_form').submit();
61
+
62
+ })
63
+ })
64
+ ```
65
+
66
+ Verify signatures on the server side. Make sure the 'challenge' string is equal one you built with JS and that it has enough details about the transaction in plain text: destination address, SWIFT, account number, full name, currency etc.
67
+
68
+ ```
69
+ def btcsend
70
+ challenge = "Send #{params[:amount]} btc to #{params[:addr]}?"
71
+ signs = cookies.delete :truefactor_response || [params[:otp0],params[:otp1]].join(':')
72
+ if current_user.valid_truefactor?(challenge, signs)
73
+ # do something...
74
+ redirect_to :back, notice: "The signature is valid! Sending #{params[:amount]} to #{params[:addr]}"
75
+ else
76
+ redirect_to :back, alert: "The signature (#{signs}) for this action (#{challenge}) is invalid"
77
+ end
78
+ end
79
+ ```
80
+
81
+
82
+ (optional) if you require other fields but tfid, like username, you might need to autofill them in models/user.rb and let the user update later.
83
+ ```
84
+ before_save do
85
+ if self.username.blank?
86
+ self.username = SecureRandom.hex
87
+ end
88
+ end
89
+ ```
90
+
91
+ ### Also
92
+
93
+ * Disable password resets by email for truefactor-enabled users
94
+
95
+ ## License
96
+
97
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_spec.rb']
8
+ end
9
+
10
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ class AddTruefactorTo<%= table_name.camelize %> < ActiveRecord::Migration
2
+ def change
3
+ add_column :<%= table_name %>, :truefactor, :text
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ Truefactor.configure do |c|
2
+ #- defaults
3
+ # c.web_origin = 'https://truefactor.io'
4
+ # c.origin = 'https://you-site-name.org'
5
+ # c.desktop_origin = 'truefactor://'
6
+ # c.tfid_type = :email
7
+ # c.origin_name = 'Truefactorized app'
8
+ # c.icon
9
+ c.model_class = '<%=class_name%>'
10
+ end
@@ -0,0 +1,47 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+ require 'rails/generators/active_record'
4
+ module Truefactor
5
+ class InstallGenerator < Rails::Generators::NamedBase
6
+ include Rails::Generators::Migration
7
+
8
+ def self.next_migration_number(dirname)
9
+ ActiveRecord::Generators::Base.next_migration_number(dirname)
10
+ end
11
+
12
+ source_root File.expand_path("../../templates", __FILE__)
13
+
14
+ desc "Adds a route, generates a migration, truefactorizes an application_controller and a model with the given NAME"
15
+
16
+ def add_truefactor_route
17
+ route "get '/truefactor', to: 'application#truefactor'"
18
+ end
19
+
20
+ def add_truefactor_migration
21
+ migration_template "migration.rb", "db/migrate/add_truefactor_to_#{table_name}.rb"
22
+ end
23
+
24
+ def truefactorize_model
25
+ content = " truefactorize\n"
26
+ class_path =
27
+ if namespaced?
28
+ class_name.to_s.split("::")
29
+ else
30
+ [class_name]
31
+ end
32
+
33
+ model_path = File.join("app", "models", "#{file_path}.rb")
34
+ inject_into_class(model_path, class_path.last, content)
35
+ end
36
+
37
+ def truefactorize_controller
38
+ content = " truefactorize\n"
39
+ controller_path = File.join("app", "controllers", "application_controller.rb")
40
+ inject_into_class(controller_path, 'ApplicationController', content)
41
+ end
42
+
43
+ def copy_initializer
44
+ template "truefactor.rb", "config/initializers/truefactor.rb"
45
+ end
46
+ end
47
+ end
@@ -1,50 +1,49 @@
1
- module Truefactor
2
- class User
3
- def truefactor_signatures(challenge, raw = false)
4
- prefix, seed1, seed2 = self.encrypted_password.split(':')
5
- unless raw
6
- stamp = Time.now.to_i / 120
7
- challenge = "#{challenge}:#{stamp}"
8
- end
9
- [to_otp(challenge, seed1), to_otp(challenge, seed2)]
10
- end
1
+ require "truefactor/version"
2
+ require 'active_support'
3
+ require 'active_record'
4
+ require 'action_controller'
5
+ require "truefactor/model"
6
+ require "truefactor/controller"
7
+ require "truefactor/helper"
8
+
9
+ require 'securerandom'
10
+ require 'uri'
11
+ require 'openssl'
11
12
 
12
- def valid_truefactor?(challenge, str)
13
- sig1, sig2 = str.gsub(/\s/,'').split(':')
13
+ module Truefactor
14
+ class << self
15
+ attr_accessor :configuration
16
+ end
14
17
 
15
- real_sig = to_otp(truefactor_signatures(challenge).join)
18
+ def self.configure
19
+ self.configuration ||= Configuration.new
20
+ yield(configuration)
21
+ end
16
22
 
17
- sig1 = to_digits(sig1)
18
- sig2 = to_digits(sig2)
23
+ def self._model_
24
+ self.configuration.model_class.constantize
25
+ end
19
26
 
20
- sig1 = to_otp(sig1 + sig2) if !sig2.blank?
27
+ class Configuration
28
+ attr_accessor :web_origin, :desktop_origin, :tfid_type, :origin_name, :origin, :icon, :model_class
21
29
 
22
- real_sig == sig1
30
+ def initialize
31
+ @web_origin = 'https://truefactor.io'
32
+ @desktop_origin = 'truefactor://'
33
+ @tfid_type = :email
34
+ @origin_name = 'Truefactorized app'
23
35
  end
24
-
25
- require 'openssl'
26
-
27
- def to_otp(m, secret = false)
28
- hex = if secret
29
- OpenSSL::HMAC.hexdigest('sha256', secret, m)
30
- else
31
- OpenSSL::Digest::SHA256.hexdigest(m)
32
- end
33
-
34
- code = (hex.to_i(16) % 10**12).to_s
36
+ end
37
+ end
35
38
 
36
- '0'*(12-code.length) + code
37
- end
39
+ ActiveSupport.on_load(:active_record) do
40
+ include Truefactor::Model
41
+ end
38
42
 
39
- def to_digits(s)
40
- s = s.to_s
41
- if s.length == 8
42
- s.to_i(32).to_s.rjust(12,'0')
43
- else
44
- s
45
- end
46
- end
47
- end
43
+ ActiveSupport.on_load(:action_controller) do
44
+ include Truefactor::Controller
48
45
  end
49
46
 
50
- #curl -u homakov https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
47
+ ActiveSupport.on_load(:action_view) do
48
+ include Truefactor::Helper
49
+ end
@@ -0,0 +1,115 @@
1
+ module Truefactor
2
+ module Controller
3
+ extend ::ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def truefactorize
7
+ class_exec do
8
+ send :include, Truefactor::Controller::TruefactorizedMethods
9
+ end
10
+ end
11
+ end
12
+
13
+ module TruefactorizedMethods
14
+ def truefactor
15
+ tfid_type = Truefactor.configuration.tfid_type
16
+ if cookies[:truefactor_state] && cookies.delete(:truefactor_state) == params[:state]
17
+ cookies[:truefactor_response] = {
18
+ value: params[:signs],
19
+ expires: 1.hour.from_now
20
+ }
21
+ return render text: "Please close this window."
22
+ elsif session[:truefactor_state] && session[:truefactor_state] == params[:state]
23
+ session.delete :truefactor_state
24
+ if params[:seeds]
25
+ user = ::Truefactor._model_.find_by(tfid_type => params[:tfid])
26
+ if user
27
+ flash[:alert] = "#{tfid_type} already exists"
28
+ else
29
+ user = ::Truefactor._model_.new
30
+ puts tfid_type
31
+ user.send "#{tfid_type}=", params[:tfid]
32
+ user.truefactor = params[:seeds]
33
+ user.save(validate: false)
34
+ truefactor_sign_in user
35
+ end
36
+ return redirect_to '/'
37
+ elsif params[:signs]
38
+ if !session[:old_env]
39
+ user = ::Truefactor._model_.find_by(tfid_type => params[:tfid])
40
+ v = if user && user.valid_truefactor?('login', params[:signs])
41
+ truefactor_sign_in user
42
+ else
43
+ flash[:alert] = "Invalid #{tfid_type} or signature"
44
+ end
45
+ return redirect_to '/'
46
+
47
+ else
48
+ session[:truefactor_signs] = params[:signs]
49
+ return redirect_to session[:old_env]["path"]+'?'+session[:old_env]["params"].to_query
50
+ end
51
+ else
52
+ raise "nothing"
53
+ end
54
+ else
55
+ redirect_to_truefactor action: "register", tfid_type: Truefactor.configuration.tfid_type
56
+ end
57
+
58
+ end
59
+
60
+ def truefactor_current_user
61
+ if session[:user_id]
62
+ @user ||= ::Truefactor._model_.find(session[:user_id])
63
+ else
64
+ false
65
+ end
66
+ end
67
+
68
+ def truefactor_sign_out
69
+ session.clear
70
+ redirect_to '/'
71
+ end
72
+
73
+ def truefactor_sign_in(user)
74
+ session[:user_id] = user.id
75
+ end
76
+
77
+ def truefactor_approve!(challenge)
78
+ path = request.env['PATH_INFO'] #url_for(action: params[:action], controller: params[:controller])
79
+ if session[:old_env] && session[:old_env]["path"] == path && session[:truefactor_signs]
80
+ # we are back
81
+ session.delete :old_env
82
+ if truefactor_current_user.valid_truefactor?(challenge, session.delete(:truefactor_signs))
83
+
84
+ return true
85
+
86
+ end
87
+ end
88
+ params.delete :action
89
+ params.delete :controller
90
+ session[:old_env] = {
91
+ path: path,
92
+ params: params
93
+ }
94
+ redirect_to_truefactor action: "auth", challenge: challenge
95
+
96
+ false
97
+ end
98
+
99
+ def redirect_to_truefactor(args)
100
+ origin = Truefactor.configuration.web_origin
101
+
102
+ session[:truefactor_state] = SecureRandom.hex
103
+ args[:state] = session[:truefactor_state]
104
+
105
+ current_origin = "#{request.protocol}#{request.host_with_port}"
106
+ args[:origin] = Truefactor.configuration.origin || current_origin
107
+
108
+ args[:origin_name] = Truefactor.configuration.origin_name
109
+ args[:icon] = Truefactor.configuration.icon
110
+
111
+ redirect_to "#{origin}/#" + args.to_query
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,9 @@
1
+ module Truefactor
2
+ module Helper
3
+ def link_to_truefactor
4
+ link_to(truefactor_path) do
5
+ image_tag 'https://truefactor.io/signin.png'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,59 @@
1
+ module Truefactor
2
+ module Model
3
+ extend ::ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def truefactorize
7
+ class_exec do
8
+ send :include, Truefactor::Model::TruefactorizedMethods
9
+ end
10
+ end
11
+ end
12
+
13
+ module TruefactorizedMethods
14
+ def truefactor_signatures(challenge, raw = false)
15
+ seed1, seed2 = self.truefactor.split(',')
16
+ unless raw
17
+ stamp = Time.now.to_i / 120
18
+ challenge = "#{challenge}:#{stamp}"
19
+ end
20
+ [to_otp(challenge, seed1), to_otp(challenge, seed2)]
21
+ end
22
+
23
+ def valid_truefactor?(challenge, str)
24
+ sig1, sig2 = str.gsub(/\s/,'').split(',')
25
+
26
+ real_sig = to_otp(truefactor_signatures(challenge).join)
27
+
28
+ sig1 = to_digits(sig1)
29
+ sig2 = to_digits(sig2)
30
+
31
+ sig1 = to_otp(sig1 + sig2) if sig2.present?
32
+
33
+ real_sig == sig1
34
+ end
35
+
36
+ def to_otp(m, secret = false)
37
+ hex =
38
+ if secret
39
+ OpenSSL::HMAC.hexdigest('sha256', secret, m)
40
+ else
41
+ OpenSSL::Digest::SHA256.hexdigest(m)
42
+ end
43
+
44
+ code = (hex.to_i(16) % 10**12).to_s
45
+
46
+ '0'*(12-code.length) + code
47
+ end
48
+
49
+ def to_digits(s)
50
+ s = s.to_s
51
+ if s.length == 8
52
+ s.to_i(32).to_s.rjust(12,'0')
53
+ else
54
+ s
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module Truefactor
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'truefactor'
3
+ require 'minitest/autorun'
@@ -0,0 +1,33 @@
1
+ require 'test_helper'
2
+
3
+ class User
4
+ attr_accessor :email
5
+ include Truefactor::Model
6
+ truefactorize
7
+ end
8
+
9
+ class Ctrlr
10
+ include Truefactor::Controller
11
+ truefactorize
12
+ end
13
+
14
+ describe 'Truefactorization' do
15
+ before do
16
+ @user = User.new
17
+ @ctrlr = Ctrlr.new
18
+ end
19
+
20
+ describe 'when model truefactorized' do
21
+ it "has truefactor methods" do
22
+ module_methods = Truefactor::Model::TruefactorizedMethods.public_instance_methods
23
+ _(@user.methods & module_methods).must_equal module_methods
24
+ end
25
+ end
26
+
27
+ describe 'when controller truefactorized' do
28
+ it "has truefactor methods" do
29
+ module_methods = Truefactor::Controller::TruefactorizedMethods.public_instance_methods
30
+ _(@ctrlr.methods & module_methods).must_equal module_methods
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'truefactor/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "truefactor"
8
+ spec.version = Truefactor::VERSION
9
+ spec.authors = ["Egor Homakov", "Alexander Yunin"]
10
+ spec.email = ["homakov@gmail.com"]
11
+ spec.summary = %q{Truefactor.io can be your only authentication option.}
12
+ spec.description = %q{Truefactor.io can be your only authentication option or you can add it to existing auth schemes such as devise, authlogic etc.}
13
+ spec.homepage = "http://truefactor.io"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.test_files = `git ls-files -- test/*`.split("\n")
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "rails", ">= 4"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest", "~> 5.0"
25
+ end
metadata CHANGED
@@ -1,23 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: truefactor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Egor Homakov
8
+ - Alexander Yunin
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-04-28 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Truefactor.io - open authentication platform
14
- email: homakov@gmail.com
12
+ date: 2016-01-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '4'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '4'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.11'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.11'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: minitest
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '5.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '5.0'
70
+ description: Truefactor.io can be your only authentication option or you can add it
71
+ to existing auth schemes such as devise, authlogic etc.
72
+ email:
73
+ - homakov@gmail.com
15
74
  executables: []
16
75
  extensions: []
17
76
  extra_rdoc_files: []
18
77
  files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/generators/templates/migration.rb
84
+ - lib/generators/templates/truefactor.rb
85
+ - lib/generators/truefactor/install_generator.rb
19
86
  - lib/truefactor.rb
20
- homepage: http://rubygems.org/gems/hola
87
+ - lib/truefactor/controller.rb
88
+ - lib/truefactor/helper.rb
89
+ - lib/truefactor/model.rb
90
+ - lib/truefactor/version.rb
91
+ - test/test_helper.rb
92
+ - test/truefactor_spec.rb
93
+ - truefactor.gemspec
94
+ homepage: http://truefactor.io
21
95
  licenses:
22
96
  - MIT
23
97
  metadata: {}
@@ -37,9 +111,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
37
111
  version: '0'
38
112
  requirements: []
39
113
  rubyforge_project:
40
- rubygems_version: 2.4.8
114
+ rubygems_version: 2.4.5
41
115
  signing_key:
42
116
  specification_version: 4
43
- summary: Truefactor
44
- test_files: []
117
+ summary: Truefactor.io can be your only authentication option.
118
+ test_files:
119
+ - test/test_helper.rb
120
+ - test/truefactor_spec.rb
45
121
  has_rdoc: