Mortimer, our multi-user, Rails-based password manager, has received a complete, front-end redesign along with multiple bug fixes and security improvements. Here are some screenshots of the latest release:
Comparing this to the original application’s design, you’ll see huge improvements in usability and aesthetics. Many thanks to Devin Ikram for the novel design work and to Ashley Cross, Skottey Forden, and Tom Rosario for the solid, cross-browser, front-end implementation.
Enjoy this latest release of Mortimer. If you’d like to participate in Mortimer’s development, don’t hesitate to fork us on Github.
Thoughtbot’s Paperclip allows easy and reliable management of attachments. Using it is as simple as adding a few columns to your model and invoking the has_attached_file class method with the desired options.
One of Paperclip’s as-yet-undocumented features is the option to pass an anonymous function to the :url, :path, and :styles parameters of the has_attached_file class method.
In the example below, a Product has many ProductImages. No problem, except that I might not want every product image to have the same style attributes (e.g., a product could have a header image of ’200×400′ and a main image of ’300×300′). Certainly one way to handle this would be to create a distinct class for each type of product image (HeaderProductImage, MainProductImage, etc.).
But another, and perhaps more interesting solution, is to pass an anonymous function to the :styles parameter. That function can then return a customized style attribute for any kind of image:
class Product < ActiveRecord::Base
has_many :images, :class_name => "ProductImage"
end
class ProductImage < ActiveRecord::Base
belongs_to :product
has_attached_file :image,
:storage => :filesystem,
:path => ":rails_root/public/images/products/:attachment/:id/:style/:basename.:extension",
:url => "/images/products/:attachment/:id/:style/:basename.:extension",
# Because the :styles key can take a Proc object as an argument, we can specify the image
# styles dynamically based on the image's label.
:styles => Proc.new {|this|
defionition = ProductImageDefinitions.detect {|spec| spec[:label] == this.instance.label}
definition[:styles].merge(:thumb => '200x200>')
}
end
When Paperclip processes the attachment, it passes itself to the anonymous function. The model can then be accessed by calling the #instance attribute on the passed-in reference (see above).
The ProductImage class defines a #label attribute. The label acts as a key to a hash, ProductImageDefinitions, which specifies styles for various kinds of product images (you might define this somewhere in config/initializers).
This allows for a high level of flexibility since adding a new kind of product image is simply a matter of modifying the ProductImageDefinitions hash. For a nice interface, you might write a module like this one to allow for the following manipulation of product images:
Not bad, right? The same kind of on-the-fly configuration can be applied to the :url and :path parameters. Thus does Paperclip’s support for anonymous functions enhance an already superb library.
For the record, I myself am still on the fence about whether this application of anonymous functions can be considered a good practice in terms of readability and maintainability.
But from the perspective of the sheer fun and practicality of the functional paradigm in Ruby, I’m going to consider it a worthwhile excursion.
Is isn’t always desirable, or even necessary, to validate every attribute in a given model with every save. For example, I recently had to build out a tabbed interface for editing products. Normally, when a user would press save, with the controller code calling update_attributes, errors would appear for attributes outside the current tab.
The need for intelligent, conditional validation begat the following module, which can be included in any ActiveRecord class:
module SelectiveAttributeValidatable
def self.included(base)
base.send(:include, InstanceMethods)
base.class_eval do
alias_method_chain :update_attributes, :check
end
end
module InstanceMethods
# Store the set of attributes passed in to #update_attributes.
def update_attributes_with_check(attrs)
@attrs_to_validate = attrs.keys.map(&:to_s)
update_attributes_without_check(attrs)
end
# Returns true if a given attribute was passed in to #update_attributes.
def should_validate?(attr)
if self.new_record?
attrs_to_validate_on_create.include?(attr)
else
@attrs_to_validate.blank? ||
@attrs_to_validate.include?(attr) ||
self.status == 'ENABLED'
end
end
# This method must be overwritten in the class
# where this module is included. Specify whichever
# attributes you want validated on create:
# ['name', 'sku']
def attrs_to_validate_on_create
[]
end
# Allows the should_validate callback to be thrown.
def method_missing(method, *args)
if method.to_s =~ /^should_validate_([_\w]+)[?]/
return should_validate?($1)
else
super
end
end
end
end
After including this module, you’ll need to add conditions to your validations, as follows:
Once you’ve implemented the conditions on your validation, any call to update_attributes will validate only the attributes included in that call. Caveat
You probably want to make sure that your objects are eventually valid. In my case, this entails storing an enabled/disabled state on the object. This way, I can specify that when the object is enabled, all of the validations should be in effect.
When writing unit tests in Rails, I’ll often make a change to an ActiveRecord instance, requiring a reload for the next assertion to pass (oversimplified):
context "A new group" do
setup do
@group = Factory(:group)
end
context "with an added entry" do
setup do
@entry = Factory(:entry, :title => "WEB", :group => @group)
@group.reload
end
should "add an entry to the group"
assert @group.entries.include?(@entry)
end
end
end
Instead of calling #reload on all the affected objects, I’ve found it useful to include a simple helper method that, when called, reloads any in-scope ActiveRecord instances:
class Test::Unit::TestCase
private
def reload_activerecord_instances
self.instance_variables.each do |ivar|
if ivar.is_a?(ActiveRecord::Base) && ivar.respond_to?(:reload)
ivar.reload
end
end
end
end
This has proven especially helpful when I’m handling several ActiveRecord objects and need to update them all at once. Cleaner, less repetitive code.
Today we release mortimer, our Rails-based password management application. The goal was to produce a secure, multi-user password vault providing basic user permissions and a simple interface. Here’s a screenshot from the current app:
Public-key Cryptography
mortimer secures password using public-key cryptography. Each user on the system has a unique key pair. When you create a password entry, mortimer stores a uniquely-encrypted version of that password entry for each user with access to that password. This ensures that any time a password changes, all users have access to the change, with no compromise in security. And since all private keys are symmetrically encrypted with the user’s password, even a compromised database is fairly useless.
Precautions
Many would still argue that “web application” and “password manager” are mutually exclusive terms. It depends. We recommend, at minimum the following:
Do not expose mortimer to the public internet.
Run it over SSL (this is, in fact, required).
Use strong passwords, and limit access to the production environment.
A work in progress
mortimer should be considered alpha as it will remain under active development. Expect improvement to the UI, along with security tweaks and cross-browser compatibility. Let us know if you find it useful.
Contributions are welcome. Clone or fork us on GitHub.
AIAIO is the blog of Alexander Interactive, covering progressive concepts in strategy, technology, branding, design and the user experience. And pickles.