Authenticating without Devise

Sounds weird but hear me out! I recently had to authenticate to a users table from a desktop app. The users table is used by a Rails app and uses Devise for authentication. This posed two issues 1) how do I hash my password properly 2) connect to database with out use of AR-JDBC.

First thing is to get a connection going. No need to use active-record-jdbc-adaptor, this is not a Rails app. You just need to require the libraries to make the connection work. I use jdbc-jdts, which is used by active-record-jdbc-adaptor. To setup your connection:

require ‘jdbc/jtds’

Jdbc::JTDS.load_driver(:require) if defined?(::Jdbc::JTDS.load_driver)
conn_str = “jdbc:jtds:sqlserver://1.2.3.4;instance=test;databaseName=test1″
connSelect = java.sql.DriverManager.get_connection(conn_str, “admin”, “secret”)

To run queries, do the following:

stmt = connSelect.create_statement
selectquery = “select * from users where email=’dude@email.com'”
rsS =stmt.execute_query(selectquery)
data = Hash.new
while (rsS.next) do
data[“first”] = rsS.getObject(“first_name”)
data[“last”] = rsS.getObject(“last_name”)
end
puts data

 

Note: To run an INSERT or UPDATE you’ll have to change use the stmt.execute_update() method. Another thing is when inserting into MSSQL, its good practice to escape your table and columns like so: INSERT INTO [customers] ([name], [user], [address]) VALUES (“John”, “john@email.com”, “123  ABC Ave”).

And thats it. To learn more, check out the active-record-jdbc-adaptor gem. Looking through the code helps you understand more.

Next, to authenticate, you’ll need to dive into the Devise gem. If you know anything about password encrypting, you’ll know that bcrypt is the defacto algorithm used for hashing passwords. To not make this sound so simple, the process actually does more than just encrypting plain text into a hash. Devise appends a pepper, a long random generated string which generated once and reused, to the plain text password. Next, Devise uses bcrypt, which prepends a salt in front of the password and encrypts the password, then stores into the database.

So you have something like this before the encryption happens:

[salt][password][pepper]

To properly authenticate to the database without Devise, you’ll need to get the pepper string from your Rails app if you use one. It should be located in config/initializers/devise.rb and look for config.pepper. If the config.pepper line is commented out, then you don’t need the pepper. You will need the encrypted password from the database in order to decrypt properly. To decrypt and check for authentication, do the following:

password_with_pepper = plain_text_password + pepper
encrypted_password = BCrypt::Password.new(encrypted_password_from_db)

if encrypted_password == password_with_pepper
puts “Your passwords match!”
else
puts “Your passwords don’t match!”
end

Golang: Serve a file from your web app

Learning Golang has been my latest crave. Its nice to have a framework to all the work for you but then you don’t really get the sense of how things work. In Rails, to send a file, you just call send_file “path/to/file.zip”, filename: “file.zip”, type: “application/zip”, x_sendfile: true and it goes to rails/actionpack/lib/action_controller/metal/data_streaming.rb and calls the send_file method and assigns the headers for you.

To send a file in Go, lets create a simple server to send a zip file.


package main

import (
"net/http"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "applicaiton/zip")
w.Header().Set("Content-Disposition", "attachment; filename='file.zip'")
http.ServeFile(w, r, "/Users/dude/file.zip")
})

http.ListenAndServe(":8080", nil)
}

1. Set the content type

2. Set the content disposition and set the name

3. Server the file

MySQL: auto timestamp

Since playing with Golang and Beego, I’ve been learning a few new things. Things that would make your live a bit easier like automatically setting the time stamp on a row when you create or update it. To do so, take a look at the following example:

CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first` varchar(20) DEFAULT NULL,
`last` varchar(20) DEFAULT NULL,
`email` varchar(20) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`active` tinyint(1) DEFAULT ‘0’,
`unlock_token` varchar(100) DEFAULT NULL,
`failed_attempts` int(1) DEFAULT ‘0’,
`locked_at` datetime DEFAULT NULL,
`unlock_token_sent_at` datetime DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NULL DEFAULT ‘0000-00-00 00:00:00′ ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

The created_at and updated_at columns, they’re both of type timestamp. For the created_at column, you want to set the default to CURRENT_TIMESTAMP. MySQL will auto fill in the current time when you create a new row in the users table. The updated_at column will get set with a timestamp when you run an INSERT statement an existing row. Neat!

By setting the users table up this way, you can create a user struct like so and create a new user without having to pass in a time.Now() for the created_at and updated_at column. Automagically taken care of on the database side.

type User struct {
First string
Last string
Email string
Password string
Active int
UnlockToken string
LockedAt sql.NullString
FailedAttempts int
UnlockTokenSentAt sql.NullString
}

db.MustExec(“INSERT INTO users (first, last, email, password, active, unlock_token, locked_at, failed_attempts) VALUES (:first, :last, :email, :password, :active, :unlock_token, :locked_at, :failed_attempts)”, User{First: “John”, Last: “Doe”, Email: “john.doe@email.com”, Password: “hashed_secret”, Active: 1,UnlockToken: “”, LockedAt: “”,FailedAttempts: “”,UnlockTokenSentAt: “”})

 

Parsing HTML with Nokogiri

Its insane what xpath can do for you. I don’t think there has been anything that Nokogiri haven’t done for me. For instance parsing this:

results = ‘<tbody>
<tr>
<td><a class=”view” href=”?id=1&amp;o=r”>All Managed Clients</a></td>
<td>1</td>
</tr>
<tr>
<td><a class=”view” href=”?id=2&amp;o=r”>All Managed Servers</a></td>
<td>0</td>
</tr>
<tr>
<td><a class=”view” href=”?id=10&amp;o=r”>AutomationUIGroup</a></td>
<td>0</td>
</tr>
<tr>
<td><a class=”view” href=”?id=4&amp;o=r”>Test JAMF Eau Claire</a></td>
<td>0</td>
</tr>
</tbody>’

This snippet of HTML will change so you can’t depend on your value to be in the same place. One good way to find the numerical value associated with the textual value is to do this:

numerical_value = Nokogiri::HTML(results).xpath(“//tr[td/a = ‘AutomationUIGroup’]/td/text()”).to_s

Breaking it down…

– Pass the HTML to Nokogiri; it subsequently returns a Nokogiri document

Nokogiri::HTML(results)

– We call the document’s xpath

xpath

– We pass in the path that we want to find. We want to look at any <tr> element that has a nested <td> element and a <a> element. The text nested in the <a> element should equal ‘AutomationUIGroup’. If that is true, we want to get the next <td> element’s text value.

“//tr[td/a = ‘AutomationUIGroup’]/td/text()”