Created
December 24, 2009 18:07
-
-
Save mindreframer/263288 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# mongo_template.rb | |
# fork of Ben Scofield's Rails MongoMapper Template (http://gist.github.com/181842) | |
# | |
# To use: | |
# rails project_name -m http://gist.github.com/gists/219223.txt | |
# remove unneeded defaults | |
run "rm public/index.html" | |
run "rm public/images/rails.png" | |
run "rm public/javascripts/controls.js" | |
run "rm public/javascripts/dragdrop.js" | |
run "rm public/javascripts/effects.js" | |
run "rm public/javascripts/prototype.js" | |
# add basic layout to start | |
file 'app/views/layouts/application.html.erb', <<-HTML | |
!!! Strict | |
%html{ "xml:lang" => "en", :lang => "en", :xmlns => "http://www.w3.org/1999/xhtml" } | |
%head | |
%title | |
Kitsune CMS | |
= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js','application' | |
= stylesheet_link_tag 'application' | |
= yield :head | |
%body | |
#content | |
#header | |
%h1 | |
#flash_messages | |
- [:notice,:error].each do |flash_type| | |
- if flash[flash_type] | |
%div{ :class => "flash_#\{flash_type\}" } | |
- unless flash[flash_type].is_a? Validatable::Errors | |
= flash[flash_type] | |
- else | |
- flash[flash_type].each do |n,msg| | |
= "#\{n\} #\{msg\}" | |
.main | |
= yield | |
HTML | |
# MongoDB FTW! | |
db_name = ask('What should I call the database? ') | |
initializer 'database.rb', <<-CODE | |
logger = Logger.new("log/mongo-#\{Rails.env\}.log") | |
MongoMapper.connection = Mongo::Connection.new('127.0.0.1',27017,:logger=>logger) | |
MongoMapper.database = "#{db_name}-#\{Rails.env\}" | |
if defined?(PhusionPassenger) | |
PhusionPassenger.on_event(:starting_worker_process) do |forked| | |
MongoMapper.database.connect_to_master if forked | |
end | |
end | |
CODE | |
file 'config/database.yml', <<-CODE | |
# Using MongoDB | |
CODE | |
# Don't need ActiveRecord | |
environment 'config.frameworks -= [:active_record]' | |
# MongoMapper | |
gem 'mongo_mapper' | |
# Testing Helper | |
file 'test/test_helper.rb', <<-CODE | |
ENV['RAILS_ENV'] = 'test' | |
require File.expand_path(File.dirname(__FILE__) + '/../config/environment') | |
require 'test_help' | |
require 'shoulda' | |
require 'mocha' | |
require 'factory_girl' | |
class ActiveSupport::TestCase | |
# Drop all columns after each test case. | |
def teardown | |
MongoMapper.database.collections.each do |coll| | |
coll.remove | |
end | |
end | |
# Make sure that each test case has a teardown | |
# method to clear the db after each test. | |
def inherited(base) | |
base.define_method teardown do | |
super | |
end | |
end | |
end | |
CODE | |
file 'lib/metaid.rb', %q{ | |
class Object | |
# The hidden singleton lurks behind everyone | |
def metaclass; class << self; self; end; end | |
alias_method :singleton_class, :metaclass | |
def meta_eval(&blk) | |
metaclass.instance_eval &blk | |
end | |
def meta_class_eval(code=nil, &blk) | |
if code.nil? | |
metaclass.class_eval &blk | |
else | |
metaclass.class_eval code, &blk | |
end | |
end | |
# Adds methods to a metaclass | |
def meta_def name, &blk | |
meta_eval { define_method name, &blk } | |
end | |
# Defines an instance method within a class | |
def class_def name, &blk | |
class_eval { define_method name, &blk } | |
end | |
end | |
} | |
file 'lib/authentication.rb', <<-HTML | |
# include this in application controller | |
module Authentication | |
protected | |
# Inclusion hook to make #current_user and #signed_in? | |
# available as ActionView helper methods. | |
def self.included(base) | |
base.send :helper_method, :current_user, :signed_in?, :authorized? if base.respond_to? :helper_method | |
end | |
# Returns true or false if the user is signed in. | |
# Preloads @current_user with the user model if they're signed in. | |
def signed_in? | |
!!current_user | |
end | |
# Accesses the current user from the session. | |
# Future calls avoid the database because nil is not equal to false. | |
def current_user | |
@current_user ||= (sign_in_from_session || sign_in_from_basic_auth) unless @current_user == false | |
end | |
# Store the given user id in the session. | |
def current_user=(new_user) | |
session[:user_id] = new_user ? new_user.id : nil | |
@current_user = new_user || false | |
end | |
# Check if the user is authorized | |
# | |
# Override this method in your controllers if you want to restrict access | |
# to only a few actions or if you want to check if the user | |
# has the correct rights. | |
# | |
# Example: | |
# | |
# # only allow nonbobs | |
# def authorized? | |
# current_user.name != "bob" | |
# end | |
# | |
def authorized?(action=nil, resource=nil, *args) | |
signed_in? | |
end | |
# Filter method to enforce a sign_in requirement. | |
# | |
# To require sign_ins for all actions, use this in your controllers: | |
# | |
# before_filter :sign_in_required | |
# | |
# To require sign_ins for specific actions, use this in your controllers: | |
# | |
# before_filter :sign_in_required, :only => [ :edit, :update ] | |
# | |
# To skip this in a subclassed controller: | |
# | |
# skip_before_filter :sign_in_required | |
# | |
def authenticate | |
authorized? || access_denied | |
end | |
# Redirect as appropriate when an access request fails. | |
# | |
# The default action is to redirect to the sign_in screen. | |
# | |
# Override this method in your controllers if you want to have special | |
# behavior in case the user is not authorized | |
# to access the requested action. For example, a popup window might | |
# simply close itself. | |
def access_denied | |
respond_to do |format| | |
format.html do | |
store_location | |
flash[:error] = "You must be logged in to do that." | |
redirect_to new_session_path | |
end | |
# format.any doesn't work in rails version < http://dev.rubyonrails.org/changeset/8987 | |
# you may want to change format.any to e.g. format.any(:js, :xml) | |
format.any do | |
request_http_basic_authentication 'Web Password' | |
end | |
end | |
end | |
# Store the URI of the current request in the session. | |
# | |
# We can return to this location by calling #redirect_back_or_default. | |
def store_location | |
session[:return_to] = request.request_uri | |
end | |
# Redirect to the URI stored by the most recent store_location call or | |
# to the passed default. Set an appropriately modified | |
# after_filter :store_location, :only => [:index, :new, :show, :edit] | |
# for any controller you want to be bounce-backable. | |
def redirect_back_or_default(default) | |
redirect_to(session[:return_to] || default) | |
session[:return_to] = nil | |
end | |
# Called from #current_user. First attempt to sign_in by the user id stored in the session. | |
def sign_in_from_session | |
if session[:user_id] | |
self.current_user = User.find_by_id(session[:user_id]) | |
end | |
end | |
# Called from #current_user. Now, attempt to sign_in by basic authentication information. | |
def sign_in_from_basic_auth | |
authenticate_with_http_basic do |email, password| | |
self.current_user = User.authenticate(email, password) | |
end | |
end | |
# This is ususally what you want; resetting the session willy-nilly wreaks | |
# havoc with forgery protection, and is only strictly necessary on sign_in. | |
# However, **all session state variables should be unset here**. | |
def sign_out_keeping_session! | |
# Kill server-side auth cookie | |
@current_user = false # not signed in, and don't do it for me | |
session[:user_id] = nil # keeps the session but kill our variable | |
# explicitly kill any other session variables you set | |
end | |
# The session should only be reset at the tail end of a form POST -- | |
# otherwise the request forgery protection fails. It's only really necessary | |
# when you cross quarantine (signed-out to signed-in). | |
def sign_out_killing_session! | |
sign_out_keeping_session! | |
reset_session | |
end | |
end | |
HTML | |
file 'app/models/user.rb', %q{require 'digest/sha1' | |
require 'bcrypt' | |
class User | |
include MongoMapper::Document | |
include Roleful | |
key :username, String, :required => true | |
key :email, String, :required => true | |
key :crypted_password, String | |
key :reset_password_code, String | |
key :reset_password_code_until, Time | |
key :role, String | |
# roleful | |
role :admin do | |
can :edit_content | |
can :edit_categories | |
end | |
role :publisher do | |
can :edit_content | |
end | |
RegEmailName = '[\w\.%\+\-]+' | |
RegDomainHead = '(?:[A-Z0-9\-]+\.)+' | |
RegDomainTLD = '(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)' | |
RegEmailOk = /\A#{RegEmailName}@#{RegDomainHead}#{RegDomainTLD}\z/i | |
def self.authenticate(email, secret) | |
u = User.first(:conditions => {:email => email.downcase}) | |
u && u.authenticated?(secret) ? u : nil | |
end | |
validates_length_of :username, :within => 6..15 | |
validates_length_of :email, :within => 6..100, :allow_blank => true | |
validates_format_of :email, :with => RegEmailOk, :allow_blank => true | |
PasswordRequired = Proc.new { |u| u.password_required? } | |
validates_presence_of :password, :if => PasswordRequired | |
validates_confirmation_of :password, :if => PasswordRequired, :allow_nil => true | |
validates_length_of :password, :minimum => 6, :if => PasswordRequired, :allow_nil => true | |
def authenticated?(secret) | |
password == secret ? true : false | |
end | |
def password | |
if crypted_password.present? | |
@password ||= BCrypt::Password.new(crypted_password) | |
else | |
nil | |
end | |
end | |
def password=(value) | |
if value.present? | |
@password = value | |
self.crypted_password = BCrypt::Password.create(value) | |
end | |
end | |
def email=(new_email) | |
new_email.downcase! unless new_email.nil? | |
write_attribute(:email, new_email) | |
end | |
def password_required? | |
crypted_password.blank? || !password.blank? | |
end | |
def set_password_code! | |
seed = "#{email}#{Time.now.to_s.split(//).sort_by {rand}.join}" | |
self.reset_password_code_until = 1.day.from_now | |
self.reset_password_code = Digest::SHA1.hexdigest(seed) | |
save! | |
end | |
end | |
} | |
file 'app/controllers/application_controller.rb', %q{class ApplicationController < ActionController::Base | |
include Authentication | |
helper :all # include all helpers, all the time | |
protect_from_forgery | |
before_filter :store_location | |
filter_parameter_logging :password | |
protected | |
def login_required | |
if !current_user | |
flash[:notice] = "Please log in." | |
redirect_to signin_url | |
else | |
return true | |
end | |
end | |
end | |
} | |
# Testing tools | |
gem 'redgreen' | |
gem 'factory_girl' | |
gem 'haml' | |
gem 'will_paginate' | |
gem 'cucumber' | |
gem 'webrat' | |
gem 'rails-footnotes' | |
# for inherited_resources | |
gem "responders" | |
gem "has_scope" | |
gem 'mongo_mapper' | |
####### plugins | |
plugin "attribute-mapper", :git => "git://github.com/therealadam/attribute_mapper.git" | |
plugin "compass", :git => "git://github.com/chriseppstein/compass.git" | |
plugin "inherited_resources", :git => "git://github.com/josevalim/inherited_resources.git" | |
plugin "roleful", :git => "git://github.com/nakajima/roleful.git" | |
plugin "paperclip", :git => "git://github.com/thoughtbot/paperclip.git" | |
if yes?("Do you want to use RSpec?") | |
plugin "rspec", :git => "git://github.com/dchelimsky/rspec.git" | |
plugin "rspec-rails", :git => "git://github.com/dchelimsky/rspec-rails.git" | |
plugin "single_test", :git => "git://github.com/grosser/single_test.git" | |
generate :rspec | |
file 'spec/spec.opts', %q{ | |
--colour | |
--format progress | |
--loadby mtime | |
--reverse | |
--drb | |
--backtrace | |
} | |
file 'spec/spec_helper.rb', %q{ | |
# This file is copied to ~/spec when you run 'ruby script/generate rspec' | |
# from the project root directory. | |
ENV["RAILS_ENV"] ||= 'test' | |
require 'spork' | |
require 'spec/spork_hack' | |
Spork.prefork do | |
require File.expand_path(File.join(File.dirname(__FILE__),'..','config','environment')) | |
require 'spec/autorun' | |
require 'spec/rails' | |
# Uncomment the next line to use webrat's matchers | |
#require 'webrat/integrations/rspec-rails' | |
# Requires supporting files with custom matchers and macros, etc | |
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f} | |
Spec::Runner.configure do |config| | |
# == Mock Framework | |
config.mock_with :mocha | |
# config.mock_with :flexmock | |
# config.mock_with :rr | |
end | |
end | |
} | |
file 'spec/spork_hack.rb', %q{ | |
begin | |
require 'spork/app_framework/rails' | |
module Spork::AppFramework::Rails::NinjaPatcher | |
# views are preloaded <-> spork must be restarted for view changes | |
def delay_eager_view_loading | |
puts "removed because i am too slow..." | |
end | |
# do not preload application files <-> fast test start | |
# not needed when config.cache_classes = false | |
# def delay_app_preload | |
# ::Rails::Initializer.send(:define_method, :load_application_classes) do | |
# end | |
# end | |
end | |
rescue | |
end | |
} | |
else | |
gem 'shoulda' | |
end | |
generate :haml, '--rails' | |
generate :cucumber | |
# Gem management | |
rake 'gems:install' | |
rake 'gems:unpack' | |
#rake 'rails:freeze:gems' | |
# source control | |
file '.gitignore', <<-FILES | |
.DS_Store | |
**/.DS_Store | |
log/* | |
tmp/* | |
tmp/**/* | |
config/database.yml | |
coverage/* | |
coverage/**/* | |
FILES | |
git :init | |
git :add => '.' | |
git :commit => '-a -m "Initial commit"' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment