wristband 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. data/.DS_Store +0 -0
  2. data/Gemfile +14 -0
  3. data/Gemfile.lock +88 -0
  4. data/README.md +113 -0
  5. data/Rakefile +21 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/application_controller.rb +10 -0
  8. data/app/controllers/sessions_controller.rb +34 -0
  9. data/app/controllers/users_controller.rb +34 -0
  10. data/app/mailers/user_mailer.rb +33 -0
  11. data/app/models/session_user.rb +59 -0
  12. data/app/models/user.rb +52 -0
  13. data/app/views/layouts/application.html.erb +14 -0
  14. data/app/views/sessions/new.html.haml +15 -0
  15. data/app/views/user_mailer/email_verification.text.html.rhtml +7 -0
  16. data/app/views/user_mailer/email_verification.text.plain.rhtml +9 -0
  17. data/app/views/user_mailer/forgot_password.text.html.rhtml +10 -0
  18. data/app/views/user_mailer/forgot_password.text.plain.rhtml +10 -0
  19. data/app/views/users/show.html.haml +6 -0
  20. data/config/application.rb +15 -0
  21. data/config/boot.rb +13 -0
  22. data/config/database.yml +16 -0
  23. data/config/environment.rb +5 -0
  24. data/config/environments/development.rb +26 -0
  25. data/config/environments/production.rb +49 -0
  26. data/config/environments/test.rb +35 -0
  27. data/config/initializers/wristband.rb +1 -0
  28. data/config/locales/en.yml +5 -0
  29. data/config/routes.rb +11 -0
  30. data/config.ru +4 -0
  31. data/db/migrate/01_create_users_table.rb +26 -0
  32. data/db/schema.rb +27 -0
  33. data/lib/generators/wristband/.DS_Store +0 -0
  34. data/lib/generators/wristband/wristband_generator.rb +56 -0
  35. data/lib/wristband/application_extensions.rb +67 -0
  36. data/lib/wristband/authority_check.rb +160 -0
  37. data/lib/wristband/support.rb +28 -0
  38. data/lib/wristband/user_extensions.rb +89 -0
  39. data/lib/wristband.rb +86 -0
  40. data/public/robots.txt +5 -0
  41. data/script/rails +6 -0
  42. data/test/dummy/user.rb +13 -0
  43. data/test/test_helper.rb +78 -0
  44. data/test/unit/has_authorities_test.rb +86 -0
  45. data/test/unit/session_user_test.rb +8 -0
  46. data/test/unit/user_test.rb +105 -0
  47. data/wristband.gemspec +107 -0
  48. metadata +209 -0
@@ -0,0 +1,35 @@
1
+ Wristband::Application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb
3
+
4
+ # The test environment is used exclusively to run your application's
5
+ # test suite. You never need to work with it otherwise. Remember that
6
+ # your test database is "scratch space" for the test suite and is wiped
7
+ # and recreated between test runs. Don't rely on the data there!
8
+ config.cache_classes = true
9
+
10
+ # Log error messages when you accidentally call methods on nil.
11
+ config.whiny_nils = true
12
+
13
+ # Show full error reports and disable caching
14
+ config.consider_all_requests_local = true
15
+ config.action_controller.perform_caching = false
16
+
17
+ # Raise exceptions instead of rendering exception templates
18
+ config.action_dispatch.show_exceptions = false
19
+
20
+ # Disable request forgery protection in test environment
21
+ config.action_controller.allow_forgery_protection = false
22
+
23
+ # Tell Action Mailer not to deliver emails to the real world.
24
+ # The :test delivery method accumulates sent emails in the
25
+ # ActionMailer::Base.deliveries array.
26
+ config.action_mailer.delivery_method = :test
27
+
28
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
29
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
30
+ # like if you have constraints or database-specific column types
31
+ # config.active_record.schema_format = :sql
32
+
33
+ # Print deprecation notices to the stderr
34
+ config.active_support.deprecation = :stderr
35
+ end
@@ -0,0 +1 @@
1
+ require 'wristband'
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
data/config/routes.rb ADDED
@@ -0,0 +1,11 @@
1
+ Rails::Application.routes.draw do
2
+
3
+ post '/login', :to => 'sessions#create'
4
+ get '/login', :to => 'sessions#new'
5
+ get '/logout', :to => 'sessions#destroy'
6
+ match '/forgot_password', :to => 'sessions#forgot_password'
7
+
8
+ resources :users
9
+ match '/register', :to => 'users#new'
10
+
11
+ end
data/config.ru ADDED
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Wristband::Application
@@ -0,0 +1,26 @@
1
+ class CreateUsersTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :email
5
+ t.string :email_validation_key
6
+ t.datetime :validated_at
7
+ t.string :password_crypt, :limit => 40
8
+ t.string :password_salt, :limit => 40
9
+ t.string :remember_token
10
+ t.string :role
11
+ t.timestamps
12
+ # --- Other useful fields ---
13
+ # t.string :first_name
14
+ # t.string :last_name
15
+ # t.string :address
16
+ # t.string :city
17
+ # t.string :state
18
+ # t.string :zip
19
+ # t.string :ip
20
+ end
21
+ end
22
+
23
+ def self.down
24
+ drop_table :users
25
+ end
26
+ end
data/db/schema.rb ADDED
@@ -0,0 +1,27 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended to check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(:version => 1) do
14
+
15
+ create_table "users", :force => true do |t|
16
+ t.string "email"
17
+ t.string "email_validation_key"
18
+ t.datetime "validated_at"
19
+ t.string "password_crypt", :limit => 40
20
+ t.string "password_salt", :limit => 40
21
+ t.string "remember_token"
22
+ t.string "role"
23
+ t.datetime "created_at"
24
+ t.datetime "updated_at"
25
+ end
26
+
27
+ end
Binary file
@@ -0,0 +1,56 @@
1
+ class WristbandGenerator < Rails::Generators::Base
2
+ include Rails::Generators::Migration
3
+
4
+ source_root File.expand_path('../../../..', __FILE__)
5
+
6
+ def generate_models
7
+ copy_file 'app/models/user.rb', 'app/models/user.rb'
8
+ copy_file 'app/models/session_user.rb', 'app/models/session_user.rb'
9
+ end
10
+
11
+ def generate_controllers
12
+ copy_file 'app/controllers/users_controller.rb', 'app/controllers/users_controller.rb'
13
+ copy_file 'app/controllers/sessions_controller.rb', 'app/controllers/sessions_controller.rb'
14
+ end
15
+
16
+ def generate_views
17
+ copy_file 'app/views/users/show.html.haml', 'app/views/users/show.html.haml'
18
+ copy_file 'app/views/sessions/new.html.haml', 'app/views/sessions/new.html.haml'
19
+
20
+ end
21
+ def generate_user_mailer
22
+ copy_file 'app/mailers/user_mailer.rb', 'app/mailers/user_mailer.rb'
23
+ copy_file 'app/views/user_mailer/forgot_password.text.html.rhtml', 'app/views/user_mailer/forgot_password.text.html.rhtml'
24
+ copy_file 'app/views/user_mailer/forgot_password.text.plain.rhtml', 'app/views/user_mailer/forgot_password.text.plain.rhtml'
25
+ copy_file 'app/views/user_mailer/email_verification.text.html.rhtml', 'app/views/user_mailer/email_verification.text.html.rhtml'
26
+ copy_file 'app/views/user_mailer/email_verification.text.plain.rhtml', 'app/views/user_mailer/email_verification.text.plain.rhtml'
27
+ end
28
+
29
+ def generate_migration
30
+ destination = File.expand_path('db/migrate/01_create_users_table.rb', self.destination_root)
31
+ migration_dir = File.dirname(destination)
32
+ destination = self.class.migration_exists?(migration_dir, 'create_users_table')
33
+
34
+ if destination
35
+ puts "\e[0m\e[31mFound existing create_users_table.rb migration. Remove it if you want to regenerate.\e[0m"
36
+ else
37
+ migration_template 'db/migrate/01_create_users_table.rb', 'db/migrate/create_users_table.rb'
38
+ end
39
+ end
40
+
41
+ def self.next_migration_number(dirname)
42
+ orm = Rails.configuration.generators.options[:rails][:orm]
43
+ require "rails/generators/#{orm}"
44
+ "#{orm.to_s.camelize}::Generators::Base".constantize.next_migration_number(dirname)
45
+ end
46
+
47
+ # def generate_routes
48
+ # route "get '/login', :to => 'sessions#new'"
49
+ # route "post '/login', :to => 'sessions#create'"
50
+ # route "get '/logout', :to => 'sessions#destroy'"
51
+ # route "match '/forgot_password', :to => 'users#forgot_password'"
52
+ # route "resources :users"
53
+ # route "match '/register', :to => 'users#new'"
54
+ # end
55
+
56
+ end
@@ -0,0 +1,67 @@
1
+ module Wristband
2
+ module ApplicationExtensions
3
+ def self.included(base)
4
+ base.send(:extend, Wristband::ApplicationExtensions::ClassMethods)
5
+ base.send(:include, Wristband::ApplicationExtensions::InstanceMethods)
6
+ base.send(:helper_method, :logged_in?, :current_user) if base.respond_to?(:helper_method)
7
+ end
8
+
9
+ module ClassMethods
10
+ # ...
11
+ end
12
+
13
+ module InstanceMethods
14
+ def login(session_user)
15
+ login_as_user(session_user.user, session_user.remember_me)
16
+ end
17
+
18
+ def login_as_user(user, remember_me=false)
19
+ self.current_user = user
20
+ if remember_me
21
+ token = Support.encrypt_with_salt(user.id.to_s, Time.now.to_f.to_s)
22
+ cookies[:login_token] = { :value => token, :expires => 2.weeks.from_now.utc }
23
+ user.update_attribute(:remember_token, token)
24
+ end
25
+ end
26
+
27
+ # Logs a user out and deletes the remember_token.
28
+ def logout
29
+ current_user.update_attribute(:remember_token, nil) if current_user
30
+ cookies.delete(:login_token)
31
+ reset_session
32
+ end
33
+
34
+ # Returns true if a user is logged in
35
+ def logged_in?
36
+ !!current_user
37
+ end
38
+
39
+ # Returns the current user in session. Use this on your views and controllers.
40
+ def current_user
41
+ @current_user ||= (session[:user_id] and ::User.find_by_id(session[:user_id]))
42
+ end
43
+
44
+ # Sets the current user in session
45
+ def current_user=(user)
46
+ @current_user = user
47
+ session[:user_id] = (user and user.id)
48
+ end
49
+
50
+ # Logs a user automatically from his cookie
51
+ #
52
+ # You can use this function as a before filter on your controllers.
53
+ def login_from_cookie
54
+ return if (logged_in? or !cookies[:login_token])
55
+ self.current_user = ::User.find_by_remember_token(cookies[:login_token])
56
+ end
57
+
58
+ # You can use this function as a before filter on your controllers that require autentication.
59
+ #
60
+ # If the user is not logged in +respond_not_logged_in+ will be called.
61
+ def login_required
62
+ logged_in?
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,160 @@
1
+ # = AuthorityCheck
2
+ # The different user authorities are defined in a separate class so as to reduce
3
+ # clutter in the User model itself.
4
+ #
5
+ # class User < ActiveRecord::Base
6
+ # wristband :has_authorities => true
7
+ # end
8
+ #
9
+ # This will refer to the class UserAuthorityCheck for all authority tests, but the
10
+ # name of this module can be defined as required:
11
+ #
12
+ # class User < ActiveRecord::Base
13
+ # has_authorities => :permissions
14
+ # end
15
+ #
16
+ # That would reference the class UserPermissions instead for all tests.
17
+ #
18
+ # A sample authority checking class is defined as:
19
+ #
20
+ # class UserAuthorityCheck < AuthorityCheck
21
+ # def wear_shoes?
22
+ # unless (@user.name.match(/^a/i))
23
+ # fail!("Only people with names that start with 'A' can wear shoes.")
24
+ # end
25
+ # end
26
+ # end
27
+ #
28
+ # <b>Note the syntax: </b>All authority checks are defined as ending with a trailing question mark
29
+ # character.
30
+ #
31
+ # A check is considered to have passed if
32
+ # * a call to <tt>allow!</tt> has been made, or
33
+ # * no calls to <tt>fail!</tt> have been made.
34
+ #
35
+ # Once defined, the user authorities are checked via a call to a User instance:
36
+ #
37
+ # user.has_authority_to?(:wear_shoes)
38
+ #
39
+ # While the <tt>has_authority_to?</tt> method returns only true or false, a call to
40
+ # <tt>has_objections_to?</tt> will return nil on success or any error messages if there
41
+ # is a failure.
42
+ #
43
+ #
44
+ # ==== Passing parameters to the authority methods
45
+ #
46
+ # Any call to these tests may include options in the form of a Hash:
47
+ #
48
+ # user.has_authority_to?(:send_message, :text => "Foo bar")
49
+ #
50
+ # These options can be acted upon within the authority check:
51
+ #
52
+ # def send_message?
53
+ # if (options[:text].match(/foo/i))
54
+ # fail!("Messages may not contain forbidden words.")
55
+ # end
56
+ # end
57
+ #
58
+ # ==== Before chains
59
+ #
60
+ # In addition to defining straight tests, a chain can be defined to run before
61
+ # any of the tests themselves. This allows certain calls to be over-ruled. For
62
+ # example:
63
+ #
64
+ # before_check :allow_if_admin!
65
+ #
66
+ # def allow_if_admin!
67
+ # if (@user.is_admin?)
68
+ # allow!
69
+ # end
70
+ # end
71
+ #
72
+ # In this case, the <tt>allow_if_admin!</tt> method will be called before any checks are performed. If
73
+ # the <tt>allow!</tt> method is executed, all subsequent tests are halted and the check
74
+ # is considered to have passed.
75
+
76
+ class AuthorityCheck
77
+ attr_accessor :user
78
+ attr_accessor :options
79
+
80
+ def initialize(user, test_method, options = { })
81
+ self.user = user
82
+ self.options = options
83
+
84
+ @test_method = "#{test_method}?".to_sym
85
+
86
+ @result = nil
87
+ end
88
+
89
+ # Checkes if the user is allowed to do something.
90
+ # Returns <tt>true</tt> or <tt>false</tt>
91
+ def allowed_to?
92
+ execute_tests!
93
+
94
+ # Either explicitly allowed (true) or not given any reasons as to why
95
+ # not (nil, empty)
96
+ (@result === true or (@result === nil and @reasons.blank?)) ? true : false
97
+ end
98
+
99
+ def denied_for_reasons
100
+ @reasons = [ ]
101
+
102
+ allowed_to? ? nil : @reasons
103
+ end
104
+
105
+
106
+ class << self
107
+ def check_chain
108
+ @check_chain ||= [ ]
109
+ end
110
+
111
+ def check_chain=(value)
112
+ @check_chain = value
113
+ end
114
+
115
+ def before_check(method, options = { })
116
+ self.check_chain += remap_chain_methods([ method ])
117
+ end
118
+
119
+ def check_alias_as(original, *aliases)
120
+ aliases.flatten.each do |alias_name|
121
+ alias_method alias_name, original
122
+ end
123
+ end
124
+ end
125
+
126
+
127
+
128
+ protected
129
+ def allow!
130
+ @result = true
131
+ end
132
+
133
+ def fail!(message)
134
+ if (@reasons and message)
135
+ @reasons << message
136
+ end
137
+
138
+ @result = false
139
+ end
140
+
141
+ def execute_tests!
142
+ self.class.check_chain.each do |method|
143
+ case (method)
144
+ when Symbol, String
145
+ send(method)
146
+ else
147
+ method.call
148
+ end
149
+
150
+ # Stop evaluating if this test called allow!
151
+ return if (@result === true)
152
+ end
153
+
154
+ self.send(@test_method)
155
+ end
156
+
157
+ def self.remap_chain_methods(methods)
158
+ methods
159
+ end
160
+ end
@@ -0,0 +1,28 @@
1
+ module Wristband
2
+ module Support
3
+ CONSONANTS = %w( b c d f g h j k l m n p qu r s t v w x z ch cr fr nd ng nk nt ph pr rd sh sl sp st th tr )
4
+ VOWELS = %w( a e i o u y )
5
+
6
+ def random_string(length = 8)
7
+ (1 .. length).collect { |n|
8
+ (n % 2 != 0) ? CONSONANTS[rand(CONSONANTS.size)] : VOWELS[rand(VOWELS.size)]
9
+ }.to_s[0, length]
10
+ end
11
+ module_function :random_string
12
+
13
+ def encrypt_with_salt(password, salt)
14
+ return password unless (salt and !salt.empty?)
15
+
16
+ Digest::SHA1.hexdigest([ password, salt ].to_s)
17
+ end
18
+ module_function :encrypt_with_salt
19
+
20
+ def random_salt(length = nil)
21
+ salt = Digest::SHA1.hexdigest([ rand, rand, random_string(64), rand, rand ].to_s)
22
+
23
+ length ? salt[0, length] : salt
24
+ end
25
+ module_function :random_salt
26
+
27
+ end
28
+ end
@@ -0,0 +1,89 @@
1
+ module Wristband
2
+ module UserExtensions
3
+ def self.included(base)
4
+ base.send(:extend, Wristband::UserExtensions::ClassMethods)
5
+ base.send(:include, Wristband::UserExtensions::InstanceMethods)
6
+ base.send(:extend, Wristband::Support)
7
+ end
8
+
9
+ module ClassMethods
10
+ def authenticate(email, password)
11
+ self.execute_authentication_chain(self, self.wristband[:before_authentication_chain]) == false and return
12
+ user = nil
13
+ wristband[:login_with_fields].find do |field|
14
+ user = send("find_by_#{field}", email)
15
+ end
16
+ (user and user.password_match?(password)) || return
17
+ self.execute_authentication_chain(user, self.wristband[:after_authentication_chain]) == false and return
18
+ user
19
+ end
20
+
21
+ def execute_authentication_chain(object, list)
22
+ list.each do |func|
23
+ case func
24
+ when Symbol,String
25
+ object.send(func) == false and return false
26
+ when Proc
27
+ func.call(object) == false and return false
28
+ end
29
+ end
30
+ end
31
+
32
+ def verify_email!(email_validation_key)
33
+ if user = find_by_email_validation_key(email_validation_key)
34
+ user.update_attribute(:validated_at, Time.now.to_s(:db))
35
+ user
36
+ else
37
+ raise UserVerificationError, 'We were not able to verify your account or it may have been verified already. Please contact us for assistance.'.t
38
+ end
39
+ end
40
+
41
+ def roles_for_select
42
+ self.class.wristband[:roles].collect{ |k| [ k.to_s.titleize, k.to_s] }
43
+ end
44
+
45
+ end
46
+
47
+ module InstanceMethods
48
+
49
+ def has_authority_to?(action, options = { })
50
+ self.class.wristband[:authority_class].new(self, action, options).allowed_to?
51
+ end
52
+
53
+ def has_objections_to?(action, options = { })
54
+ self.class.wristband[:authority_class].new(self, action, options).denied_for_reasons
55
+ end
56
+
57
+ def initialize_salt
58
+ self.password_salt = Wristband::Support.random_salt
59
+ end
60
+
61
+ def initialize_token
62
+ self.remember_token = Wristband::Support.random_salt(16)
63
+ end
64
+
65
+ def encrypt_password
66
+ initialize_salt if new_record?
67
+ return if self.password.blank?
68
+ self.send("#{self.class.wristband[:password_column]}=", Wristband::Support.encrypt_with_salt(self.password, self.password_salt))
69
+ end
70
+
71
+ def password_match?(string)
72
+ self.send(self.class.wristband[:password_column]) == Wristband::Support.encrypt_with_salt(string, self.password_salt)
73
+ end
74
+
75
+ def password_crypted?
76
+ self.password_salt and !self.password_salt.empty?
77
+ end
78
+
79
+ def password_crypt=(value)
80
+ if (value != read_attribute(:password_crypt))
81
+ initialize_token
82
+ end
83
+
84
+ write_attribute(:password_crypt, value)
85
+ end
86
+
87
+ end
88
+ end
89
+ end
data/lib/wristband.rb ADDED
@@ -0,0 +1,86 @@
1
+ require 'wristband/user_extensions'
2
+ require 'wristband/support'
3
+ require 'wristband/application_extensions'
4
+ require 'wristband/authority_check'
5
+
6
+ module Wristband
7
+
8
+ VERSION = "1.0.0"
9
+
10
+ class Engine < ::Rails::Engine; end
11
+
12
+ class << self
13
+ def included base #:nodoc:
14
+ base.extend ClassMethods
15
+ end
16
+ end
17
+
18
+ module ClassMethods
19
+ def wristband(options={})
20
+ options[:login_with] ||= [:email]
21
+ options[:before_authentication] ||= []
22
+ options[:after_authentication] ||= []
23
+ options[:has_authorities] ||= false
24
+ options[:roles] ||= []
25
+
26
+ class_eval do
27
+ include Wristband::UserExtensions
28
+
29
+ options[:password_column] ||= :password_crypt
30
+
31
+ # These two are used on the login form
32
+ attr_accessor :password
33
+ attr_accessor :password_confirmation
34
+
35
+ before_save :encrypt_password
36
+
37
+ # Add roles
38
+ unless options[:roles].blank?
39
+ options[:roles].each do |role|
40
+ define_method "is_#{role}?" do
41
+ self.role.to_s == role.to_s
42
+ end
43
+ end
44
+ end
45
+
46
+ class << self
47
+ attr_accessor :wristband
48
+ end
49
+ end
50
+
51
+ self.wristband = {
52
+ :login_with_fields => [options[:login_with]].flatten,
53
+ :before_authentication_chain => [options[:before_authentication]].flatten,
54
+ :after_authentication_chain => [options[:after_authentication]].flatten,
55
+ :password_column => options[:password_column],
56
+ :roles => options[:roles]
57
+ }
58
+
59
+ if options[:has_authorities]
60
+ self.wristband[:authority_class] = UtilityMethods.interpret_class_specification(self, options[:has_authorities])
61
+ end
62
+ end
63
+ end
64
+
65
+ module UtilityMethods
66
+ def self.interpret_class_specification(model_class, with_class)
67
+ case (with_class)
68
+ when Symbol
69
+ "#{model_class.class_name}#{with_class.to_s.camelcase}".constantize
70
+ when String
71
+ with_class.constantize
72
+ when true
73
+ "#{model_class.name}AuthorityCheck".constantize
74
+ else
75
+ with_class
76
+ end
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+
83
+ ActiveRecord::Base.send(:extend, Wristband::ClassMethods)
84
+ ActionController::Base.send(:include, Wristband::ApplicationExtensions)
85
+
86
+ class UserVerificationError < StandardError; end
data/public/robots.txt ADDED
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
data/script/rails ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,13 @@
1
+ TestDummy.declare(User) do
2
+ dummy :email do
3
+ Faker::Internet.email
4
+ end
5
+
6
+ dummy :password do
7
+ 'passpass'
8
+ end
9
+
10
+ dummy :role do
11
+ User::ROLES[0]
12
+ end
13
+ end