Clean up trailing and leading whitespace
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
<div class="accordion-inner">
|
||||
<p class="desc">
|
||||
The application's API returns a model object (user or users). Using respond_with, the API returns the full model object. It is simple but exposes information such as the user's password and other user attributes that you may wish to keep invisible.
|
||||
</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,7 +51,7 @@
|
||||
<p class="desc">
|
||||
The <i>as_json</i> method referenced in the comments section of the index action exists within the user model in order to override and safely protect our model from only rendering certain attributes. It is unused (commented out), app/models/user.rb:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
<pre class="ruby">
|
||||
# Instead of the entire user object being returned, we can use this to filter.
|
||||
def as_json
|
||||
super(only: [:user_id, :email, :first_name, :last_name])
|
||||
@@ -69,14 +69,14 @@
|
||||
X-Request-Id: c3b0a57861087c0b827aab231747ef0c
|
||||
X-Runtime: 0.051734
|
||||
Connection: close
|
||||
|
||||
|
||||
{"admin":false,"created_at":"2014-01-23T16:17:10Z","email":
|
||||
"jack@metacorp.com","first_name":"Jack","id":2,"last_name":"Mannino","password":
|
||||
"b46dd2888a0904972649cc880a93f4dd","updated_at":"2014-01-23T16:17:10Z","user_id":2}
|
||||
</pre>
|
||||
<p class="desc">
|
||||
Note that all attributes associated with this user are returned via the API.
|
||||
</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -121,7 +121,7 @@
|
||||
Connection: close
|
||||
|
||||
{"email":"jack@metacorp.com","first_name":"Jack","last_name":"Mannino","user_id":2}
|
||||
</pre>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
before_save <span style="background-color:yellow">:hash_password</span>
|
||||
|
||||
|
||||
def self.authenticate(email, password)
|
||||
auth = nil
|
||||
user = find_by_email(email)
|
||||
@@ -52,21 +52,21 @@
|
||||
auth = user
|
||||
else
|
||||
raise "Incorrect Password!"
|
||||
end
|
||||
end
|
||||
else
|
||||
raise "#{email} doesn't exist!"
|
||||
end
|
||||
return auth
|
||||
end
|
||||
|
||||
|
||||
def hash_password
|
||||
if self.password.present?
|
||||
self.password = <span style="background-color:yellow">Digest::MD5.hexdigest(password)</span>
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
</pre>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -88,7 +88,7 @@
|
||||
<p class="desc">
|
||||
A simple solution here would be to enforce a per-user salt in creating a BCrypt hash. You would need to alter the db schema to add a password_salt and password_hash columns to the table.
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
<pre class="ruby">
|
||||
def self.authenticate(email, password)
|
||||
user = find_by_email(email)
|
||||
if user and user.password_hash == <span style="background-color:yellow">BCrypt::Engine.hash_secret(password, user.password_salt)</span>
|
||||
@@ -97,14 +97,14 @@
|
||||
"Invalid Credentials Supplied"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def hash_password
|
||||
if self.password.present?
|
||||
<span style="background-color:yellow">self.password_salt = BCrypt::Engine.generate_salt</span>
|
||||
<span style="background-color:yellow">self.password_hash = BCrypt::Engine.hash_secret(self.password, self.password_salt)</span>
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"***-**-" << self.decrypt_ssn[-4,4]
|
||||
end
|
||||
</pre>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,11 +65,11 @@
|
||||
<li>Only authorized users can access decrypted copies of the data </li>
|
||||
<li>Use a strong algorithm</li>
|
||||
<li>Strong key is generated, protected from unauthorized access, and key change is planned for.</li><br/>
|
||||
</p>
|
||||
|
||||
</p>
|
||||
|
||||
<p class="desc">
|
||||
In the following code, we demonstrate switching from the storage of full SSN(s) in clear-text to storing them in the AES-256 encrypted format. The first thing to do is build the encrypt and decrypt functions. These can be found within app/models/work_info.rb.
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def encrypt_ssn
|
||||
aes = OpenSSL::Cipher::Cipher.new(cipher_type)
|
||||
@@ -87,7 +87,7 @@
|
||||
aes.iv = iv if iv != nil
|
||||
aes.update(self.encrypted_ssn) + aes.final
|
||||
end
|
||||
|
||||
|
||||
def key
|
||||
raise "Key Missing" if !(KEY)
|
||||
KEY
|
||||
@@ -101,7 +101,7 @@
|
||||
def cipher_type
|
||||
'aes-256-cbc'
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
<p class="desc">
|
||||
Also within the WorkInfo model, we add the following line of code...
|
||||
</p>
|
||||
@@ -109,12 +109,12 @@
|
||||
before_save :encrypt_ssn
|
||||
</pre>
|
||||
<p class="desc">
|
||||
The remaining pieces are:
|
||||
The remaining pieces are:
|
||||
<li> We "seed" the database with per-user initialization vectors (IV) and store them within the key_management table</li>
|
||||
<li> Separate production and development encryption keys. Production keys should be stored in an HSM, environment variable, etc. but never within the source code. Development keys are irrelevant if not being used for real data</li>
|
||||
<li> Change the view where SSNs are called and rendered to the user so that the "last_four" method is called instead</li>
|
||||
<li> For new user's who are registering, we create an initialization specific to their account</li>
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
# SEED DATA
|
||||
work_info.each do |wi|
|
||||
@@ -133,7 +133,7 @@
|
||||
elsif Rails.env.development?
|
||||
KEY = "123456789101112123456789101112123456789101112"
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
<pre class="ruby">
|
||||
# CHANGE VIEW TO CALL LAST FOUR METHOD (app/views/work_info/index.html.erb)
|
||||
<%= CGI.unescapeHTML("<td class="ssn"><%= @user.work_info.last_four %></td>") %>
|
||||
@@ -147,7 +147,7 @@
|
||||
work_info.build_key_management(:iv => SecureRandom.hex(32))
|
||||
performance.build(POPULATE_PERFORMANCE.shuffle.first)
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user