devise_latcheable 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +113 -0
- data/app/controllers/devise_latcheable/registrations_controller.rb +1 -1
- data/app/views/devise_latcheable/registrations/new.html.erb +2 -2
- data/lib/devise_latcheable/model.rb +40 -8
- data/lib/devise_latcheable/version.rb +1 -1
- data/lib/devise_latcheable.rb +8 -1
- data/plugin_info +37 -0
- metadata +4 -3
- data/lib/devise_latcheable/adapter.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5d81c85f9712118198e61d829a08203f276ddcf
|
4
|
+
data.tar.gz: ebcf6bde53094b7b440f69832fc46c593a6e6d0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27b46a8e8e57dd152a1b6f0a47b1477c73569f2116a04be57e5d9d3c0fb3376e82ff0cb33741fd172333711151f1047dcb202d62bfd86b159bd600e0e247bfd9
|
7
|
+
data.tar.gz: d0e8a81267811bc39da94edcd16c673cc308203c7166261f5a396ba94865b83f9fec2d9b011b8494d3a7dd8516bb54b2d88c10834377d81184c6572a873e22f4
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# devise\_latcheable
|
2
|
+
This gem adds an extra security layer using a Latch account to any Rails app
|
3
|
+
using the devise gem.
|
4
|
+
|
5
|
+
You can find more info about Latch at https://latch.elevenpaths.com
|
6
|
+
|
7
|
+
## How to install and configure it
|
8
|
+
|
9
|
+
1. Install and configure devise gem. You can follow the guide at
|
10
|
+
https://github.com/plataformatec/devise
|
11
|
+
|
12
|
+
2. Add the gem to your Gemfile
|
13
|
+
```ruby
|
14
|
+
gem 'devise_latcheable'
|
15
|
+
```
|
16
|
+
|
17
|
+
3. Add latcheable to the module list on your users model
|
18
|
+
```ruby
|
19
|
+
class User < ActiveRecord::Base
|
20
|
+
devise :database_authenticatable, :latcheable, :registerable,
|
21
|
+
:recoverable, :rememberable, :trackable, :validatable
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
4. Run the generator in your console with the name of the model you're using.
|
26
|
+
That will generate a new migration and will copy the main configuration file.
|
27
|
+
```bash
|
28
|
+
rails generate devise_latcheable MODEL_NAME
|
29
|
+
```
|
30
|
+
|
31
|
+
5. Run rake db:migrate to apply the new migration
|
32
|
+
|
33
|
+
6. Modify config/latch.yml file with your app id and secret codes
|
34
|
+
|
35
|
+
7. Modify your routes.rb file to change your devise\_for controllers option
|
36
|
+
```ruby
|
37
|
+
devise_for :users, controllers: { registrations: 'devise_latcheable/registrations' }
|
38
|
+
```
|
39
|
+
|
40
|
+
## Using devise\_latcheable
|
41
|
+
The good thing about devise\_latcheable is that you can just forget about Latch,
|
42
|
+
because the gem will take care of it for you. If you know how to use devise, you
|
43
|
+
already know how to use devise\_latcheable!
|
44
|
+
|
45
|
+
For more advanced users, the information below will be useful in case of
|
46
|
+
modifying or expanding the functionality of devise\_latcheable.
|
47
|
+
|
48
|
+
### Custom register forms and pair code
|
49
|
+
devise\_latcheable comes with a register form for your users. To use it, you
|
50
|
+
just need to declare the use of the registrations controller that comes with
|
51
|
+
the gem as explained in step seven of 'how to install and configure it'.
|
52
|
+
|
53
|
+
You can use your custom controller and your custom views if you want, just go
|
54
|
+
ahead to the 'Configuring views' or 'Configuring controllers' section of
|
55
|
+
devise's readme. You just need to remember that you need a pair
|
56
|
+
code to register the user and authenticate it with Latch.
|
57
|
+
|
58
|
+
An attr\_accessor called 'latch\_pair\_code' is registered on your application
|
59
|
+
users model to take care of that. This attribute isn't saved on your database
|
60
|
+
but is needed when a user is being created. devise\_latcheable will check this
|
61
|
+
code against Latch. If the user pair code is valid, the user will be registered
|
62
|
+
and logged in in your rails app.
|
63
|
+
```ruby
|
64
|
+
# Example saving an user and pairing it
|
65
|
+
user = User.new
|
66
|
+
user.email = 'crresse@gmail.com'
|
67
|
+
user.password = '123123123'
|
68
|
+
user.password_confirmation = '123123123'
|
69
|
+
user.latch_pair_code = 'fw2kW5L'
|
70
|
+
user.save # true if no errors
|
71
|
+
```
|
72
|
+
|
73
|
+
### Using latch optionally
|
74
|
+
A instance attribute called 'latch\_enabled' is added to your users model to
|
75
|
+
specify if that instance is going to be authenticated against Latch. This
|
76
|
+
attribute is set to 'true' if 'always\_enabled' is set to 'true' in the config
|
77
|
+
file.
|
78
|
+
|
79
|
+
If you set it to a value different from 'true', devise will forget about
|
80
|
+
Latch, and will authenticate and validate the user using the remaining
|
81
|
+
modules that you declared on your model.
|
82
|
+
```ruby
|
83
|
+
# Suppose that 'always_enabled' is set to true
|
84
|
+
user = User.new
|
85
|
+
user.email = 'crresse@gmail.com'
|
86
|
+
user.password = '123123123'
|
87
|
+
user.password_confirmation = '123123123'
|
88
|
+
user.latch_enabled = false
|
89
|
+
user.save # Latch wont be checked here, since we specified that we dont want it enabled
|
90
|
+
```
|
91
|
+
|
92
|
+
### Unpairing
|
93
|
+
A user is unpaired from Latch when you destroy the user instance if it has latch
|
94
|
+
enabled on it. When you do so, the user's latch app notifies him that the app is
|
95
|
+
now unpaired from latch.
|
96
|
+
```ruby
|
97
|
+
user = User.find_by name: 'Test'
|
98
|
+
user.destroy # Latch is unpaired at this point, and the user will receive a notification in it latch app
|
99
|
+
```
|
100
|
+
|
101
|
+
### Account id
|
102
|
+
When a user pairs with Latch, devise\_latcheable needs to hold a reference to
|
103
|
+
the user's latch id to check his latch status. You can get a user's latch id
|
104
|
+
calling latch\_account\_id on it.
|
105
|
+
```ruby
|
106
|
+
user = User.find_by name: 'Test'
|
107
|
+
user.latch_account_id
|
108
|
+
```
|
109
|
+
|
110
|
+
## Demo
|
111
|
+
There is a app already configured with devise and devise\_latcheable at
|
112
|
+
[this repo](https://github.com/CarlosRdrz/latch_app) for demo and
|
113
|
+
development purposes.
|
@@ -4,6 +4,6 @@ class DeviseLatcheable::RegistrationsController < Devise::RegistrationsControlle
|
|
4
4
|
protected
|
5
5
|
|
6
6
|
def configure_permitted_parameters
|
7
|
-
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :
|
7
|
+
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :latch_pair_code) }
|
8
8
|
end
|
9
9
|
end
|
@@ -22,8 +22,8 @@
|
|
22
22
|
</div>
|
23
23
|
|
24
24
|
<div class="field">
|
25
|
-
<%= f.label :
|
26
|
-
<%= f.text_field :
|
25
|
+
<%= f.label :latch_pair_code %><br />
|
26
|
+
<%= f.text_field :latch_pair_code, autocomplete: "off" %>
|
27
27
|
</div>
|
28
28
|
|
29
29
|
<div class="actions">
|
@@ -7,7 +7,7 @@ module Devise
|
|
7
7
|
# We only use pair code to pair the user with latch. Once it is
|
8
8
|
# paired, we dont need the pair code anymore, so we wont save
|
9
9
|
# it on the database
|
10
|
-
attr_accessor :
|
10
|
+
attr_accessor :latch_pair_code
|
11
11
|
|
12
12
|
after_initialize :latch_enable
|
13
13
|
|
@@ -19,31 +19,63 @@ module Devise
|
|
19
19
|
latch_enabled
|
20
20
|
end
|
21
21
|
|
22
|
+
# => Checks if the app lock is open
|
23
|
+
# @returns true if the latch is unlocked
|
24
|
+
# @returns false if the latch is locked or if there was an error
|
22
25
|
def latch_unlocked?
|
23
26
|
return true unless latch_enabled?
|
24
27
|
return false if latch_account_id.nil?
|
25
|
-
|
28
|
+
api_response = ::DeviseLatcheable.api.status latch_account_id
|
29
|
+
|
30
|
+
if api_response.error.nil?
|
31
|
+
key = api_response.data['operations'].keys.first
|
32
|
+
status = api_response.data['operations'][key]['status']
|
33
|
+
return (status == 'on')
|
34
|
+
else
|
35
|
+
return false
|
36
|
+
end
|
26
37
|
end
|
27
38
|
|
39
|
+
# => Removes the pairing from latch
|
40
|
+
# If an error occurs, it copies the error at errors base
|
41
|
+
# so you can access it with model_instance.errors
|
42
|
+
# @returns true on success, false otherwise
|
28
43
|
def latch_unpair!
|
29
44
|
return true unless latch_enabled?
|
30
45
|
return true if latch_account_id.nil?
|
31
|
-
|
46
|
+
api_response = ::DeviseLatcheable.api.unpair latch_account_id
|
47
|
+
|
48
|
+
if api_response.error.nil?
|
49
|
+
return true
|
50
|
+
else
|
51
|
+
errors.add(:base, "Latch error: #{api_response.error.message}")
|
52
|
+
return false
|
53
|
+
end
|
32
54
|
end
|
33
55
|
|
56
|
+
# => Pairs an user with the server.
|
57
|
+
# If an error occurs, it copies the error at errors base
|
58
|
+
# so you can access it with model_instance.errors
|
59
|
+
# On success, it sets latch_account_id to the value that
|
60
|
+
# latch server sent on its response
|
61
|
+
# @returns true on success, false otherwise
|
34
62
|
def latch_pair!
|
35
63
|
return true unless latch_enabled?
|
64
|
+
api_response = ::DeviseLatcheable.api.pair latch_pair_code
|
36
65
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
66
|
+
if api_response.error.nil?
|
67
|
+
self.latch_account_id = api_response.data['accountId']
|
68
|
+
return true
|
69
|
+
else
|
70
|
+
errors.add(:base, "Latch error: #{api_response.error.message}")
|
41
71
|
return false
|
42
72
|
end
|
43
73
|
end
|
44
74
|
|
45
75
|
def latch_enable
|
46
|
-
|
76
|
+
if ::DeviseLatcheable.config['always_enabled'] == true
|
77
|
+
self.latch_enabled = true
|
78
|
+
end
|
47
79
|
end
|
48
80
|
end
|
49
81
|
end
|
data/lib/devise_latcheable.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
require 'latchsdk'
|
2
2
|
require 'devise'
|
3
|
-
require 'devise_latcheable/adapter'
|
4
3
|
require 'devise_latcheable/model'
|
5
4
|
require 'devise_latcheable/strategy'
|
6
5
|
require 'devise_latcheable/engine'
|
7
6
|
|
8
7
|
module DeviseLatcheable
|
8
|
+
# The config file
|
9
|
+
mattr_accessor :config
|
10
|
+
self.config = YAML.load(File.read('config/latch.yml'))
|
11
|
+
|
12
|
+
# We instantiate only one api client per app
|
13
|
+
mattr_accessor :api
|
14
|
+
self.api = ::Latch.new ::DeviseLatcheable.config['app_id'],
|
15
|
+
::DeviseLatcheable.config['app_secret']
|
9
16
|
end
|
10
17
|
|
11
18
|
Devise.add_module :latcheable,
|
data/plugin_info
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
This plugin is a ruby gem that adds a module for the devise gem. It implements
|
2
|
+
latch authentication usable by any rails app using devise.
|
3
|
+
|
4
|
+
Rails is one of the most used frameworks to build web apps. A high number of
|
5
|
+
startups use Rails to build their products, and almost every one of them uses
|
6
|
+
some kind of user handling to allow sign-up and sign-in capabilities to their
|
7
|
+
websites.
|
8
|
+
|
9
|
+
Devise is a gem used for user authentication. It is valued as the #1 must-have
|
10
|
+
gem for any rails app by a large number of websites, blogs and professionals.
|
11
|
+
It implements user sign-in and sign-up in a easy and modularizable way, so that
|
12
|
+
developers can forget about user handling and focus on building their apps.
|
13
|
+
|
14
|
+
Although there's a publicly available latch ruby sdk, it can be somehow
|
15
|
+
confusing adding Latch to a rails app, since it involves knowledge about how
|
16
|
+
user registration and logging in implementations work, and gems precisaly
|
17
|
+
abstract these implementations.
|
18
|
+
|
19
|
+
This plugin adds Latch as a Devise module. This means that any rails app that
|
20
|
+
is using devise can add an extra layer of security with latch. And the
|
21
|
+
good thing is that if they know how to use Devise they already know how to use
|
22
|
+
Devise Latcheable!
|
23
|
+
|
24
|
+
There is an app already configured with Devise and Devise Latcheable at
|
25
|
+
https://github.com/CarlosRdrz/latch_app. To run it, you just need to modify
|
26
|
+
the file config/latch.yml and write there your app id and secret.
|
27
|
+
This app is only an example, but shows how the module works.
|
28
|
+
|
29
|
+
In the future, it will be great if Devise Latcheable is merged with Devise. The
|
30
|
+
authors of Devise did this before with other modules, and it eliminates steps
|
31
|
+
for installation and configuration of Devise Latcheable, therefore simplyfing
|
32
|
+
the process of implementing Latch in any app.
|
33
|
+
|
34
|
+
I think that Devise Latcheable should win the contest because it allows a lot
|
35
|
+
of apps to implement Latch in a easy way, and this can encourage the usage of
|
36
|
+
Latch in the rails community, which is one of the most active developers
|
37
|
+
communities of the world.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_latcheable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Rodriguez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: devise
|
@@ -59,11 +59,11 @@ extensions: []
|
|
59
59
|
extra_rdoc_files: []
|
60
60
|
files:
|
61
61
|
- Gemfile
|
62
|
+
- README.md
|
62
63
|
- app/controllers/devise_latcheable/registrations_controller.rb
|
63
64
|
- app/views/devise_latcheable/registrations/new.html.erb
|
64
65
|
- devise_latcheable.gemspec
|
65
66
|
- lib/devise_latcheable.rb
|
66
|
-
- lib/devise_latcheable/adapter.rb
|
67
67
|
- lib/devise_latcheable/engine.rb
|
68
68
|
- lib/devise_latcheable/model.rb
|
69
69
|
- lib/devise_latcheable/strategy.rb
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/generators/templates/README
|
74
74
|
- lib/generators/templates/latch.yml
|
75
75
|
- lib/generators/templates/migration.rb
|
76
|
+
- plugin_info
|
76
77
|
homepage:
|
77
78
|
licenses:
|
78
79
|
- MIT
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module Devise
|
2
|
-
module Latch
|
3
|
-
@yaml_config = YAML.load(File.read("config/latch.yml"))
|
4
|
-
@latch_instance = ::Latch.new @yaml_config['app_id'], @yaml_config['app_secret']
|
5
|
-
|
6
|
-
# => Pairs an user with the server.
|
7
|
-
# @returns Account ID on success and nil on failure
|
8
|
-
def self.pair(code)
|
9
|
-
res = @latch_instance.pair code
|
10
|
-
return nil if res.data.nil?
|
11
|
-
res.data['accountId']
|
12
|
-
end
|
13
|
-
|
14
|
-
# => Checks if the app lock is open
|
15
|
-
def self.unlocked?(account_id)
|
16
|
-
res = @latch_instance.status account_id
|
17
|
-
return false unless res.error.nil?
|
18
|
-
|
19
|
-
key = res.data['operations'].keys.first
|
20
|
-
status = res.data['operations'][key]['status']
|
21
|
-
status == 'on'
|
22
|
-
end
|
23
|
-
|
24
|
-
# => Removes the pairing from lath
|
25
|
-
def self.unpair(account_id)
|
26
|
-
res = @latch_instance.unpair account_id
|
27
|
-
res.error.nil? ? true : false
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.config
|
31
|
-
@yaml_config
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|