Comments (10)
@JIucToyxuu is right, but I'll expound. attr_encrypted
converts the otp_secret
into raw byte data that Mongoid refuses to write into a String
field:
user = User.find(id)
user.otp_secret = User.generate_otp_secret
user.save!
user.encrypted_otp_secret
=> "z\xD5\xCEK\x05?Q\x8C\aY\xBB\xF1\x01\x92\x12u\xC24~F\x04\x1C=\x8D\x11\b\xCB\x11,B\x94\xCBj6(\xE4\x8B\x85\x0E\xD0"
User.find(id).encrypted_otp_secret
=> nil
My solution, instead of playing with force_encoding
is to write Base64 to the database instead:
# app/models/concerns/base64_encoded.rb
module Base64Encoded
def base64_encoded(*attributes)
attributes.each do |attribute|
define_method :"#{attribute}=" do |value|
value = Base64.encode64(value) if value
self.write_attribute(attribute, value)
end
define_method attribute do
value = self.read_attribute(attribute)
value = Base64.decode64(value) if value
value
end
end
end
end
extend Base64Encoded
field :encrypted_otp_secret, type: String
field :encrypted_otp_secret_iv, type: String
field :encrypted_otp_secret_salt, type: String
field :consumed_timestep, type: Integer
field :otp_required_for_login, type: Boolean, default: false
# ensure all encrypted attributes are base64 encoded
# so Mongoid can write them into a String field
base64_encoded :encrypted_otp_secret
base64_encoded :encrypted_otp_secret_iv
base64_encoded :encrypted_otp_secret_salt
from devise-two-factor.
We have a fork at http://github.com/tinfoil/attr_encrypted that patches in Mongoid support. So long as you have the proper fields declared, it should work with something like:
field :encrypted_otp_secret, :type => String
field :encrypted_otp_secret_iv, :type => String
field :encrypted_otp_secret_salt, :type => String
attr_encrypted :otp_secret, :key => ENV['OTP_SECRET_DB_KEY']
from devise-two-factor.
I couldn't get this working with rails 3 & mongoid. Interestingly, I did get attr_encrypted to work on an arbitrary other field, but I could never get the otp_secret to be decrypted correctly. I decided to use https://github.com/Houdini/two_factor_authentication instead.
from devise-two-factor.
That's a great idea. I don't know how well attr_encrypted plays with Mongoid, but I'll investigate when I have some free-time later.
from devise-two-factor.
@bsedat I'm using your fork of attr_encrypted for my rails 3 app using mongoid. I'm trying to get this set up, but nothing is getting saved to the encrypted fields when I set the otp_secret and save the user.
Here's an example from the console:
1.9.3-head :003 > u.otp_secret = User.generate_otp_secret
=> "u7n3t3fmn3q2rwnduvcwrpzplkp6nhxgv7fnerytmzym46rk2him74l2hhti4kfijhp7w6fmwqvhnqxzbcparznop62edmivcyiy7q5hdsak3v62smptmvahhipb25sc"
1.9.3-head :004 > u.save!
=> true
1.9.3-head :006 > u.inspect
=> "#<User _id: 531a3cdcc8eb1cd895000008, created_at: 2014-03-07 21:40:44 UTC, updated_at: 2014-10-24 21:50:51 UTC, invited_by_type: nil, invited_by_field: nil, invited_by_id: nil, email: \"FAKEFAKEFAKE\", encrypted_password: \"BLAHBLAHBLAH\", authentication_token: \"WAHWAHWAH\", [...bunch of stuff], encrypted_otp_secret: nil, encrypted_otp_secret_iv: nil, encrypted_otp_secret_salt: nil, active: false, [...bunch of other stuff]>"
Any ideas why the otp fields aren't saving?
I've tried all the combinations of fields that I can think of on my user model after reading several other attr_encrypted issues
Here's the last thing I tried, which is maximum fields:
## Two-Factor
attr_accessible :otp_attempt
field :otp_required_for_login, type:Boolean, default:true ## TODO remove this--should not be on by default
field :otp_secret, type:String
field :otp_secret_iv, type:String
field :otp_secret_salt, type:String
field :encrypted_otp_secret, type:String
field :encrypted_otp_secret_iv, type:String
field :encrypted_otp_secret_salt, type:String
attr_encrypted :otp_secret, :key => 'super_secret_two_factor_key', :encode => true, :mode => :per_attribute_iv_and_salt
attr_encrypted :otp_secret_iv, :key => 'super_secret_two_factor_key', :encode => true, :mode => :per_attribute_iv_and_salt
attr_encrypted :otp_secret_salt, :key => 'super_secret_two_factor_key', :encode => true, :mode => :per_attribute_iv_and_salt
from devise-two-factor.
I got things to save by explicitly calling update_attribute, but now when I try to access the unencrypted fields I get "OpenSSL::Cipher::CipherError: bad decrypt"
from devise-two-factor.
I override some methods in my model and this work with mongoid. BTW: i use standard attr_encrypted(not fork).
def encrypted_otp_secret=(value)
self.write_attribute(:encrypted_otp_secret, value.force_encoding("ISO-8859-1").encode("UTF-8"))
end
def encrypted_otp_secret
if self.read_attribute(:encrypted_otp_secret).nil?
super
else
self.read_attribute(:encrypted_otp_secret).encode("ISO-8859-1").force_encoding('ASCII-8BIT')
end
end
P.S. But this not clear way, i think.
from devise-two-factor.
Is there a solution for this? It does not work with mongoid (5.1.6).... I tried everything from here, still receiving nil...
from devise-two-factor.
@JIucToyxuu can you explain it bit more. probably with gist ?
from devise-two-factor.
@QuinnWilton any update on this issue ?
from devise-two-factor.
Related Issues (20)
- Clarification about setup with rails 6 HOT 1
- missing attribute: encrypted_otp_secret
- Remove "Rails 4" misleading sentences from readme
- NoMethodError Exception: undefined method `tr' for nil:NilClass HOT 1
- Require email verification when enabling Authenticator App type
- Generator throws exception HOT 1
- `Devise.add_module(:two_factor_authenticatable)` should be inserted on top
- calling super in the two factor strategy is problematic...
- Remove the old `otp_secret_encryption_key` in the UPGRADING.md guide
- Git tag for v4.1.0 appears to be missing HOT 2
- No changelog for 4.1.0
- `user.current_otp` code sent to user are always invalid HOT 1
- [question] mass users update?
- Not required on every login HOT 1
- Rails 7.1 on 4.x HOT 1
- Support for Rails 7.1 HOT 3
- ActiveRecord::Encryption::Errors::Decryption error on login after upgrade to Rails 7.1 defaults HOT 3
- Backup codes aren't written to the database so can't be used HOT 1
- Clarification on GHSA-chcr-x7hc-8fp8 HOT 8
- Lockbox instead of ActiveRecord encrypted attributes HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from devise-two-factor.