├── .gitignore ├── .ruby-gemset ├── .ruby-version ├── Gemfile ├── Gemfile.lock ├── README ├── README.textile ├── Rakefile ├── app ├── assets │ ├── javascripts │ │ ├── application.js │ │ └── home.js.coffee │ └── stylesheets │ │ ├── application.css.scss │ │ ├── bootstrap_and_overrides.css.scss │ │ └── home.css.scss ├── controllers │ ├── application_controller.rb │ ├── home_controller.rb │ └── users_controller.rb ├── helpers │ ├── application_helper.rb │ └── home_helper.rb ├── mailers │ └── .gitkeep ├── models │ ├── .gitkeep │ ├── ability.rb │ ├── role.rb │ └── user.rb └── views │ ├── devise │ ├── registrations │ │ ├── edit.html.erb │ │ └── new.html.erb │ ├── sessions │ │ └── new.html.erb │ └── shared │ │ └── _links.html.erb │ ├── home │ └── index.html.erb │ ├── layouts │ ├── _messages.html.erb │ ├── _navigation.html.erb │ └── application.html.erb │ └── users │ ├── _user.html.erb │ ├── index.html.erb │ └── show.html.erb ├── config.ru ├── config ├── application.example.yml ├── application.rb ├── application.yml ├── boot.rb ├── cucumber.yml ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── backtrace_silencers.rb │ ├── devise.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── rolify.rb │ ├── secret_token.rb │ ├── session_store.rb │ ├── simple_form.rb │ ├── simple_form_bootstrap.rb │ └── wrap_parameters.rb ├── locales │ ├── devise.en.yml │ ├── en.yml │ └── simple_form.en.yml └── routes.rb ├── db ├── migrate │ ├── 20120418171104_devise_create_users.rb │ ├── 20120418171110_rolify_create_roles.rb │ └── 20120418171112_add_name_to_users.rb ├── schema.rb └── seeds.rb ├── features ├── step_definitions │ ├── email_steps.rb │ └── user_steps.rb ├── support │ ├── email_spec.rb │ ├── env.rb │ └── paths.rb └── users │ ├── sign_in.feature │ ├── sign_out.feature │ ├── sign_up.feature │ ├── user_edit.feature │ └── user_show.feature ├── lib ├── assets │ └── .gitkeep ├── tasks │ ├── .gitkeep │ └── cucumber.rake └── templates │ └── erb │ └── scaffold │ └── _form.html.erb ├── log └── .gitkeep ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── humans.txt └── robots.txt ├── script ├── cucumber └── rails ├── spec ├── controllers │ ├── home_controller_spec.rb │ └── users_controller_spec.rb ├── factories │ └── users.rb ├── models │ └── user_spec.rb ├── spec_helper.rb └── support │ └── devise.rb └── vendor ├── assets ├── javascripts │ └── .gitkeep └── stylesheets │ └── .gitkeep └── plugins └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------------------------- 2 | # Ignore these files when commiting to a git repository. 3 | # 4 | # See http://help.github.com/ignore-files/ for more about ignoring files. 5 | # 6 | # The original version of this file is found here: 7 | # https://github.com/RailsApps/rails-composer/blob/master/files/gitignore.txt 8 | # 9 | # Corrections? Improvements? Create a GitHub issue: 10 | # http://github.com/RailsApps/rails-composer/issues 11 | #---------------------------------------------------------------------------- 12 | 13 | # bundler state 14 | /.bundle 15 | /vendor/bundle/ 16 | /vendor/ruby/ 17 | 18 | # minimal Rails specific artifacts 19 | db/*.sqlite3 20 | /log/* 21 | /tmp/* 22 | 23 | # various artifacts 24 | **.war 25 | *.rbc 26 | *.sassc 27 | .rspec 28 | .redcar/ 29 | .sass-cache 30 | /config/config.yml 31 | /config/database.yml 32 | /coverage.data 33 | /coverage/ 34 | /db/*.javadb/ 35 | /db/*.sqlite3 36 | /doc/api/ 37 | /doc/app/ 38 | /doc/features.html 39 | /doc/specs.html 40 | /public/cache 41 | /public/stylesheets/compiled 42 | /public/system/* 43 | /spec/tmp/* 44 | /cache 45 | /capybara* 46 | /capybara-*.html 47 | /gems 48 | /specifications 49 | rerun.txt 50 | pickle-email-*.html 51 | 52 | # If you find yourself ignoring temporary files generated by your text editor 53 | # or operating system, you probably want to add a global ignore instead: 54 | # git config --global core.excludesfile ~/.gitignore_global 55 | # 56 | # Here are some files you may want to ignore globally: 57 | 58 | # scm revert files 59 | **.orig 60 | 61 | # Mac finder artifacts 62 | .DS_Store 63 | 64 | # Netbeans project directory 65 | /nbproject/ 66 | 67 | # RubyMine project files 68 | .idea 69 | 70 | # Textmate project files 71 | /*.tmproj 72 | 73 | # vim artifacts 74 | **.swp 75 | 76 | # Ignore application configuration 77 | /config/application.yml 78 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | rails3-bootstrap-devise-cancan 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.0.0 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | ruby '2.0.0' 3 | gem 'rails', '3.2.14' 4 | gem 'sqlite3' 5 | group :assets do 6 | gem 'sass-rails', '~> 3.2.3' 7 | gem 'coffee-rails', '~> 3.2.1' 8 | gem 'uglifier', '>= 1.0.3' 9 | end 10 | gem 'jquery-rails' 11 | gem 'bootstrap-sass' 12 | gem 'cancan' 13 | gem 'devise' 14 | gem 'figaro' 15 | gem 'rolify' 16 | gem 'simple_form' 17 | group :development do 18 | gem 'better_errors' 19 | gem 'binding_of_caller', :platforms=>[:mri_19, :mri_20, :rbx] 20 | gem 'quiet_assets' 21 | end 22 | group :development, :test do 23 | gem 'factory_girl_rails' 24 | gem 'rspec-rails' 25 | end 26 | group :test do 27 | gem 'capybara' 28 | gem 'cucumber-rails', :require=>false 29 | gem 'database_cleaner', '1.0.1' 30 | gem 'email_spec' 31 | gem 'launchy' 32 | end 33 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (3.2.14) 5 | actionpack (= 3.2.14) 6 | mail (~> 2.5.4) 7 | actionpack (3.2.14) 8 | activemodel (= 3.2.14) 9 | activesupport (= 3.2.14) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | journey (~> 1.0.4) 13 | rack (~> 1.4.5) 14 | rack-cache (~> 1.2) 15 | rack-test (~> 0.6.1) 16 | sprockets (~> 2.2.1) 17 | activemodel (3.2.14) 18 | activesupport (= 3.2.14) 19 | builder (~> 3.0.0) 20 | activerecord (3.2.14) 21 | activemodel (= 3.2.14) 22 | activesupport (= 3.2.14) 23 | arel (~> 3.0.2) 24 | tzinfo (~> 0.3.29) 25 | activeresource (3.2.14) 26 | activemodel (= 3.2.14) 27 | activesupport (= 3.2.14) 28 | activesupport (3.2.14) 29 | i18n (~> 0.6, >= 0.6.4) 30 | multi_json (~> 1.0) 31 | addressable (2.3.5) 32 | arel (3.0.2) 33 | bcrypt-ruby (3.1.1) 34 | better_errors (0.9.0) 35 | coderay (>= 1.0.0) 36 | erubis (>= 2.6.6) 37 | binding_of_caller (0.7.2) 38 | debug_inspector (>= 0.0.1) 39 | bootstrap-sass (2.3.2.1) 40 | sass (~> 3.2) 41 | builder (3.0.4) 42 | cancan (1.6.10) 43 | capybara (2.1.0) 44 | mime-types (>= 1.16) 45 | nokogiri (>= 1.3.3) 46 | rack (>= 1.0.0) 47 | rack-test (>= 0.5.4) 48 | xpath (~> 2.0) 49 | coderay (1.0.9) 50 | coffee-rails (3.2.2) 51 | coffee-script (>= 2.2.0) 52 | railties (~> 3.2.0) 53 | coffee-script (2.2.0) 54 | coffee-script-source 55 | execjs 56 | coffee-script-source (1.6.3) 57 | cucumber (1.3.6) 58 | builder (>= 2.1.2) 59 | diff-lcs (>= 1.1.3) 60 | gherkin (~> 2.12.0) 61 | multi_json (~> 1.7.5) 62 | multi_test (>= 0.0.2) 63 | cucumber-rails (1.4.0) 64 | capybara (>= 1.1.2) 65 | cucumber (>= 1.2.0) 66 | nokogiri (>= 1.5.0) 67 | rails (>= 3.0.0) 68 | database_cleaner (1.0.1) 69 | debug_inspector (0.0.2) 70 | devise (3.0.3) 71 | bcrypt-ruby (~> 3.0) 72 | orm_adapter (~> 0.1) 73 | railties (>= 3.2.6, < 5) 74 | warden (~> 1.2.3) 75 | diff-lcs (1.2.4) 76 | email_spec (1.5.0) 77 | launchy (~> 2.1) 78 | mail (~> 2.2) 79 | erubis (2.7.0) 80 | execjs (2.0.0) 81 | factory_girl (4.2.0) 82 | activesupport (>= 3.0.0) 83 | factory_girl_rails (4.2.1) 84 | factory_girl (~> 4.2.0) 85 | railties (>= 3.0.0) 86 | figaro (0.7.0) 87 | bundler (~> 1.0) 88 | rails (>= 3, < 5) 89 | gherkin (2.12.1) 90 | multi_json (~> 1.3) 91 | hike (1.2.3) 92 | i18n (0.6.5) 93 | journey (1.0.4) 94 | jquery-rails (3.0.4) 95 | railties (>= 3.0, < 5.0) 96 | thor (>= 0.14, < 2.0) 97 | json (1.8.0) 98 | launchy (2.3.0) 99 | addressable (~> 2.3) 100 | mail (2.5.4) 101 | mime-types (~> 1.16) 102 | treetop (~> 1.4.8) 103 | mime-types (1.24) 104 | mini_portile (0.5.1) 105 | multi_json (1.7.9) 106 | multi_test (0.0.2) 107 | nokogiri (1.6.0) 108 | mini_portile (~> 0.5.0) 109 | orm_adapter (0.4.0) 110 | polyglot (0.3.3) 111 | quiet_assets (1.0.2) 112 | railties (>= 3.1, < 5.0) 113 | rack (1.4.5) 114 | rack-cache (1.2) 115 | rack (>= 0.4) 116 | rack-ssl (1.3.3) 117 | rack 118 | rack-test (0.6.2) 119 | rack (>= 1.0) 120 | rails (3.2.14) 121 | actionmailer (= 3.2.14) 122 | actionpack (= 3.2.14) 123 | activerecord (= 3.2.14) 124 | activeresource (= 3.2.14) 125 | activesupport (= 3.2.14) 126 | bundler (~> 1.0) 127 | railties (= 3.2.14) 128 | railties (3.2.14) 129 | actionpack (= 3.2.14) 130 | activesupport (= 3.2.14) 131 | rack-ssl (~> 1.3.2) 132 | rake (>= 0.8.7) 133 | rdoc (~> 3.4) 134 | thor (>= 0.14.6, < 2.0) 135 | rake (10.1.0) 136 | rdoc (3.12.2) 137 | json (~> 1.4) 138 | rolify (3.2.0) 139 | rspec-core (2.14.5) 140 | rspec-expectations (2.14.2) 141 | diff-lcs (>= 1.1.3, < 2.0) 142 | rspec-mocks (2.14.3) 143 | rspec-rails (2.14.0) 144 | actionpack (>= 3.0) 145 | activesupport (>= 3.0) 146 | railties (>= 3.0) 147 | rspec-core (~> 2.14.0) 148 | rspec-expectations (~> 2.14.0) 149 | rspec-mocks (~> 2.14.0) 150 | sass (3.2.10) 151 | sass-rails (3.2.6) 152 | railties (~> 3.2.0) 153 | sass (>= 3.1.10) 154 | tilt (~> 1.3) 155 | simple_form (2.1.0) 156 | actionpack (~> 3.0) 157 | activemodel (~> 3.0) 158 | sprockets (2.2.2) 159 | hike (~> 1.2) 160 | multi_json (~> 1.0) 161 | rack (~> 1.0) 162 | tilt (~> 1.1, != 1.3.0) 163 | sqlite3 (1.3.8) 164 | thor (0.18.1) 165 | tilt (1.4.1) 166 | treetop (1.4.15) 167 | polyglot 168 | polyglot (>= 0.3.1) 169 | tzinfo (0.3.37) 170 | uglifier (2.2.0) 171 | execjs (>= 0.3.0) 172 | multi_json (~> 1.0, >= 1.0.2) 173 | warden (1.2.3) 174 | rack (>= 1.0) 175 | xpath (2.0.0) 176 | nokogiri (~> 1.3) 177 | 178 | PLATFORMS 179 | ruby 180 | 181 | DEPENDENCIES 182 | better_errors 183 | binding_of_caller 184 | bootstrap-sass 185 | cancan 186 | capybara 187 | coffee-rails (~> 3.2.1) 188 | cucumber-rails 189 | database_cleaner (= 1.0.1) 190 | devise 191 | email_spec 192 | factory_girl_rails 193 | figaro 194 | jquery-rails 195 | launchy 196 | quiet_assets 197 | rails (= 3.2.14) 198 | rolify 199 | rspec-rails 200 | sass-rails (~> 3.2.3) 201 | simple_form 202 | sqlite3 203 | uglifier (>= 1.0.3) 204 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Rails3 + Twitter Bootstrap + Devise + CanCan 2 | ============================================ 3 | 4 | You can use this project as a starting point for a Rails web application. It requires Rails 3 and uses Devise for user management and authentication, CanCan for authorization of administrator access, and Twitter Bootstrap for CSS styling. 5 | 6 | Devise 7 | http://github.com/plataformatec/devise 8 | 9 | CanCan 10 | https://github.com/ryanb/cancan 11 | 12 | Twitter Bootstrap 13 | http://twitter.github.com/bootstrap/ 14 | 15 | ________________________ 16 | 17 | For more information, please see the updated README file on GitHub: 18 | 19 | https://github.com/railsapps/rails3-bootstrap-devise-cancan 20 | 21 | ________________________ 22 | 23 | MIT License 24 | 25 | http://www.opensource.org/licenses/mit-license -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. !http://railsapps.github.io/images/rails-36x36.jpg(Rails Application for Devise with RSpec and Cucumber)! Rails 4.1 2 | 3 | For a Rails 4.1 example application for Devise with authorization, plus Bootstrap, see: 4 | 5 | * "rails-devise-pundit":https://github.com/RailsApps/rails-devise-pundit 6 | 7 | Tutorials are available for Devise: 8 | 9 | * "Rails Devise Tutorial":http://railsapps.github.io/rails-devise/ 10 | 11 | h4. Similar Examples and Tutorials 12 | 13 | This is one in a series of Rails example apps and tutorials from the "RailsApps Project":http://railsapps.github.io/. See a list of additional "Rails examples, tutorials, and starter apps":http://railsapps.github.io/rails-examples-tutorials.html. Related example applications may be useful: 14 | 15 | * "Learn Rails":https://github.com/RailsApps/learn-rails companion to the book "Learn Ruby on Rails":http://learn-rails.com/learn-ruby-on-rails.html 16 | * "Foundation and Rails":http://railsapps.github.io/rails-foundation/ shows how to integrate Foundation 17 | * "Bootstrap and Rails":http://railsapps.github.io/rails-bootstrap/ shows to integrate Bootstrap 18 | * "OmniAuth and Rails":https://github.com/RailsApps/rails-omniauth uses OmniAuth for authentication 19 | * "Devise and Rails":https://github.com/RailsApps/rails-devise uses Devise for authentication 20 | 21 | h1. !http://railsapps.github.io/images/rails-36x36.jpg(Rails Application for Devise with RSpec and Cucumber)! Rails 3.2 22 | 23 | This rails3-bootstrap-devise-cancan example application is outdated and has been replaced! For a Rails 4.1 example application for Devise with authorization, see "rails-devise-pundit":https://github.com/RailsApps/rails-devise-pundit. 24 | 25 | This Rails 3.2 example application shows how to use "Devise":https://github.com/plataformatec/devise with "CanCan":https://github.com/ryanb/cancan and "Twitter Bootstrap":http://twitter.github.com/bootstrap/. 26 | 27 | * "Devise":https://github.com/plataformatec/devise gives you ready-made authentication and user management. 28 | * "CanCan":https://github.com/ryanb/cancan provides authorization for administrator access. 29 | * "Twitter Bootstrap":http://twitter.github.com/bootstrap/ is a front-end framework for CSS styling. 30 | 31 | !http://railsapps.github.io/images/rails3-bootstrap-devise-cancan.png(Rails Application for Devise with CanCan and Twitter Bootstrap)! 32 | 33 | h2. What Is Implemented -- and What Is Not 34 | 35 | This is a demonstration application that allows you to visit a home page and see a list of users. Devise provides user management so a visitor can register with an email address and password and create an account. Devise provides authentication so access to the site can be limited to users who are registered and logged in. CanCan is used for authorization, limiting access to only an administrator for designated pages. An administrative dashboard allows the administrator to delete any user or change a user's role. 36 | 37 | The @rake db:seed@ command sets up a database with an administrator who can view a administrative page when logged in. Additional users can be added; each is restricted from accessing the administrative page. 38 | 39 | h2. Dependencies 40 | 41 | Before generating your application, you will need: 42 | 43 | * The Ruby language (version 1.9.3 or 2.0.0) 44 | * The Rails gem (version 3.2.13) 45 | 46 | See the article "Installing Rails":http://railsapps.github.io/installing-rails.html for advice about updating Rails and your development environment. 47 | 48 | h2. Getting the Application 49 | 50 | You have several options for getting the code. You can _fork_, _clone_, or _generate_. 51 | 52 | h3. Fork 53 | 54 | If you'd like to add features (or bug fixes) to improve the example application, you can fork the GitHub repo and "make pull requests":http://help.github.com/send-pull-requests/. Your code contributions are welcome! 55 | 56 | h3. Clone 57 | 58 | If you want to copy and customize the app with changes that are only useful for your own project, you can clone the GitHub repo. You'll need to search-and-replace the project name throughout the application. You probably should generate the app instead (see below). To clone: 59 | 60 |
61 | $ git clone git://github.com/RailsApps/rails3-bootstrap-devise-cancan.git 62 |63 | 64 | You'll need "git":http://git-scm.com/ on your machine. See "Rails and Git":http://railsapps.github.io/rails-git.html. 65 | 66 | h3. Generate 67 | 68 | If you want to use the project as a starter app, use the "Rails Composer":http://railsapps.github.io/rails-composer/ tool to generate a new version of the example app. You'll be able to give it your own project name when you generate the app. Generating the application gives you many additional options. 69 | 70 | To build the example application, run the command: 71 | 72 |
73 | $ rails new rails3-bootstrap-devise-cancan -m https://raw.github.com/RailsApps/rails-composer/master/composer-Rails3_2.rb -T 74 |75 | 76 | Use the @-T@ flag to skip Test::Unit files. 77 | 78 | The @$@ character indicates a shell prompt; don't include it when you run the command. 79 | 80 | This creates a new Rails app named @rails3-bootstrap-devise-cancan@ on your computer. You can use a different name if you wish. 81 | 82 | You'll see a prompt: 83 | 84 |
85 | question Install an example application? 86 | 1) I want to build my own application 87 | 2) membership/subscription/saas 88 | 3) rails-prelaunch-signup 89 | 4) rails3-bootstrap-devise-cancan 90 | 5) rails3-devise-rspec-cucumber 91 | 6) rails3-mongoid-devise 92 | 7) rails3-mongoid-omniauth 93 | 8) rails3-subdomains 94 |95 | 96 | Choose *rails3-bootstrap-devise-cancan*. The Rails Composer tool may give you other options (other choices may have been added since these notes were written). 97 | 98 | The application generator template will ask you for additional preferences: 99 | 100 |
101 | question Web server for development? 102 | 1) WEBrick (default) 103 | 2) Thin 104 | 3) Unicorn 105 | 4) Puma 106 | question Web server for production? 107 | 1) Same as development 108 | 2) Thin 109 | 3) Unicorn 110 | 4) Puma 111 | question Template engine? 112 | 1) ERB 113 | 2) Haml 114 | 3) Slim 115 | extras Set a robots.txt file to ban spiders? (y/n) 116 | extras Use or create a project-specific rvm gemset? (y/n) 117 | extras Create a GitHub repository? (y/n) 118 |119 | 120 | h4. Web Servers 121 | 122 | We recommend Thin in development for speed and less noise in the log files. 123 | 124 | If you plan to deploy to Heroku, select Thin as your production webserver. 125 | 126 | h4. Template Engine 127 | 128 | The example application uses the default "ERB" Rails template engine. Optionally, you can use another template engine, such as Haml or Slim. See instructions for "Haml and Rails":http://railsapps.github.io/rails-haml.html. 129 | 130 | h4. Other Choices 131 | 132 | Set a robots.txt file to ban spiders if you want to keep your new site out of Google search results. 133 | 134 | It is a good idea to use "rvm":https://rvm.io/, the Ruby Version Manager, and create a project-specific rvm gemset (not available on Windows). See "Installing Rails":http://railsapps.github.io/installing-rails.html. 135 | 136 | If you choose to create a GitHub repository, the generator will prompt you for a GitHub username and password. 137 | 138 | h4. Troubleshooting 139 | 140 | If you get an error "OpenSSL certificate verify failed" or "Gem::RemoteFetcher::FetchError: SSL_connect" see the article "OpenSSL errors and Rails":http://railsapps.github.io/openssl-certificate-verify-failed.html. 141 | 142 | If you get an error like this: 143 | 144 |
145 | Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. 146 | composer Running 'after bundler' callbacks. 147 | The template [...] could not be loaded. 148 | Error: You have already activated ..., but your Gemfile requires .... 149 | Using bundle exec may solve this. 150 |151 | 152 | It's due to conflicting gem versions. See the article "Rails Error: “You have already activated (…)”":http://railsapps.github.io/rails-error-you-have-already-activated.html. 153 | 154 | h3. Edit the README 155 | 156 | If you're storing the app in a GitHub repository, please edit the README files to add a description of the app and your contact info. If you don't change the README, people will think I am the author of your version of the application. 157 | 158 | h2. Getting Started 159 | 160 | See the article "Installing Rails":http://railsapps.github.io/installing-rails.html to make sure your development environment is prepared properly. 161 | 162 | h3. Use RVM 163 | 164 | I recommend using "rvm":https://rvm.io/, the Ruby Version Manager, to create a project-specific gemset for the application. If you generate the application with the Rails Composer tool, you can create a project-specific gemset. 165 | 166 | h3. Install the Required Gems 167 | 168 | Check the Gemfile to see which gems are used by this application. 169 | 170 | If you used the "Rails Composer":http://railsapps.github.io/rails-composer/ tool to generate the example app, the application template script has already run the @bundle install@ command. 171 | 172 | If not, you should run the @bundle install@ command to install the required gems on your computer: 173 | 174 |
175 | $ bundle install 176 |177 | 178 | You can check which gems are installed on your computer with: 179 | 180 |
181 | $ gem list 182 |183 | 184 | Keep in mind that you have installed these gems locally. When you deploy the app to another server, the same gems (and versions) must be available. 185 | 186 | I recommend using "rvm":https://rvm.io/, the Ruby Version Manager, to create a project-specific gemset for the application. See the article "Installing Rails":http://railsapps.github.io/installing-rails.html. 187 | 188 | h3. Configure Email 189 | 190 | This example application doesn't send email messages. However, if you want your application to send email messages (for example, if you plan to install the Devise @:confirmable@ module) you must configure the application for your email account. See the article "Send Email with Rails":http://railsapps.github.io/rails-send-email.html. 191 | 192 | h3. Configure Devise 193 | 194 | You can modify the configuration file for Devise if you want to use something other than the defaults: 195 | 196 | * *config/initializers/devise.rb* 197 | 198 | h3. Configuration File 199 | 200 | The application uses the "figaro gem":https://github.com/laserlemon/figaro to set environment variables. Credentials for your administrator account and email account are set in the *config/application.yml* file. The *.gitignore* file prevents the *config/application.yml* file from being saved in the git repository so your credentials are kept private. See the article "Rails Environment Variables":http://railsapps.github.io/rails-environment-variables.html for more information. 201 | 202 | Modify the file *config/application.yml*: 203 | 204 |
205 | # Add account credentials and API keys here. 206 | # See http://railsapps.github.io/rails-environment-variables.html 207 | # This file should be listed in .gitignore to keep your settings secret! 208 | # Each entry sets a local environment variable and overrides ENV variables in the Unix shell. 209 | # For example, setting: 210 | # GMAIL_USERNAME: Your_Gmail_Username 211 | # makes 'Your_Gmail_Username' available as ENV["GMAIL_USERNAME"] 212 | # Add application configuration variables here, as shown below. 213 | # 214 | GMAIL_USERNAME: Your_Username 215 | GMAIL_PASSWORD: Your_Password 216 | ADMIN_NAME: First User 217 | ADMIN_EMAIL: user@example.com 218 | ADMIN_PASSWORD: changeme 219 | ROLES: [admin, user, VIP] 220 |221 | 222 | Set the user name and password needed for the application to send email. 223 | 224 | If you wish, set your name, email address, and password for an administrator's account. If you prefer, you can use the default to sign in to the application and edit the account after deployment. It is always a good idea to change the administrator's password after the application is deployed. 225 | 226 | Specify roles in the configuration file. You will need an "admin" role. Change the "user" and "VIP" roles as you wish. 227 | 228 | All configuration values in the *config/application.yml* file are available anywhere in the application as environment variables. For example, @ENV["GMAIL_USERNAME"]@ will return the string "Your_Username". 229 | 230 | If you prefer, you can delete the *config/application.yml* file and set each value as an environment variable in the Unix shell. 231 | 232 | h3. Set Up a Database Seed File 233 | 234 | The *db/seeds.rb* file initializes the database with default values. To keep some data private, and consolidate configuration settings in a single location, we use the *config/application.yml* file to set environment variables and then use the environment variables in the *db/seeds.rb* file. 235 | 236 |
237 | puts 'ROLES' 238 | YAML.load(ENV['ROLES']).each do |role| 239 | Role.find_or_create_by_name({ :name => role }, :without_protection => true) 240 | puts 'role: ' << role 241 | end 242 | puts 'DEFAULT USERS' 243 | user = User.find_or_create_by_email :name => ENV['ADMIN_NAME'].dup, :email => ENV['ADMIN_EMAIL'].dup, :password => ENV['ADMIN_PASSWORD'].dup, :password_confirmation => ENV['ADMIN_PASSWORD'].dup 244 | puts 'user: ' << user.name 245 | user.add_role :admin 246 |247 | 248 | You can change the administrator name, email, and password in this file but it is better to make the changes in the *config/application.yml* file to keep the credentials private. If you decide to include your private password in the *db/seeds.rb* file, be sure to add the filename to your *.gitignore* file so that your password doesn't become available in your public GitHub repository. 249 | 250 | Note that it's not necessary to personalize the *db/seeds.rb* file before you deploy your app. You can deploy the app with an example user and then use the application's "Edit Account" feature to change name, email address, and password after you log in. Use this feature to log in as an administrator and change the user name and password to your own. 251 | 252 | The *db/seeds.rb* file reads a list of roles from the *config/application.yml* file and adds the roles to the database. In fact, any new role can be added to the roles datatable with a statement such @user.add_role :superhero@. Setting the roles in the *db/seeds.rb* file simply makes sure each role is listed and available should a user wish to change roles. 253 | 254 | You may wish to include additional sample users: 255 | 256 |
257 | user2 = User.find_or_create_by_email :name => 'Second User', :email => 'user2@example.com', :password => 'changeme', :password_confirmation => 'changeme' 258 | puts 'user: ' << user2.name 259 | user2.add_role :VIP 260 |261 | 262 | This will add a second user to the database with a "VIP" role. 263 | 264 | h3. Set the Database 265 | 266 | Prepare the database and add the default user to the database by running the commands: 267 | 268 |
269 | $ rake db:migrate 270 | $ rake db:seed 271 |272 | 273 | Use @rake db:reset@ if you want to empty and reseed the database. 274 | 275 | Set the database for running tests: 276 | 277 |
278 | $ rake db:test:prepare 279 |280 | 281 | If you’re not using "rvm":https://rvm.io/, the Ruby Version Manager, you should preface each rake command with @bundle exec@. You don’t need to use @bundle exec@ if you are using rvm version 1.11.0 or newer. 282 | 283 | h3. Change your Application's Secret Token 284 | 285 | If you've used the Rails Composer tool to generate the application, the application's secret token will be unique, just as with any Rails application generated with the @rails new@ command. 286 | 287 | However, if you've cloned the application directly from GitHub, it is crucial that you change the application's secret token before deploying your application in production mode. Otherwise, people could change their session information, and potentially access your site without permission. Your secret token should be at least 30 characters long and completely random. 288 | 289 | Get a unique secret token: 290 | 291 |
292 | rake secret 293 |294 | 295 | Edit your *config/initializers/secret_token.rb* file to add the secret token: 296 | 297 |
298 | Rails3BootstrapDeviseCancan::Application.config.secret_token = '...some really long, random string...' 299 |300 | 301 | h2. Test the App 302 | 303 | You can check that your application runs properly by entering the command: 304 | 305 | @$ rails server@ 306 | 307 | To see your application in action, open a browser window and navigate to "http://localhost:3000/":http://localhost:3000. You should see the default user listed on the home page. When you click on the user's name, you should be required to log in before seeing the user's detail page. 308 | 309 | If you are using the default values from the *config/application.yml* file, you can sign in as the administrator using: 310 | 311 | * email: user@example.com 312 | * password: changeme 313 | 314 | You'll see a navigation link for Admin. Clicking the link will display a page with a list of users at 315 | "http://localhost:3000/users":http://localhost:3000/users. 316 | 317 | If you've added a second user, (unless you've changed it) use 318 | 319 | * email: user2@example.com 320 | * password: changeme 321 | 322 | The second user will not see the Admin navigation link and will not be able to access the page at 323 | "http://localhost:3000/users":http://localhost:3000/users. 324 | 325 | Stop the server with Control-C. 326 | 327 | If you test the app by starting the web server and then leave the server running while you install new gems, you’ll have to restart the server to see any changes. The same is true for changes to configuration files in the config folder. This can be confusing to new Rails developers because you can change files in the app folders without restarting the server. Stop the server each time after testing and you will avoid this issue. 328 | 329 | h2. Deploy to Heroku 330 | 331 | For your convenience, here is a "Tutorial for Rails on Heroku":http://railsapps.github.io/rails-heroku-tutorial.html. Heroku provides low cost, easily configured Rails application hosting. 332 | 333 | Be sure to set up SSL before you make your application available in production. See the "Heroku documentation on SSL":https://devcenter.heroku.com/articles/ssl. 334 | 335 | Add this configuration parameter to the *config/application.rb* file: 336 | 337 |
338 | # Heroku requires this to be false 339 | config.assets.initialize_on_precompile=false 340 |341 | 342 | Then precompile assets, commit to git, and push to Heroku: 343 | 344 |
345 | $ rake assets:precompile 346 | $ git add -A 347 | $ git commit -m "assets compiled for Heroku" 348 | $ git push heroku master 349 |350 | 351 | You'll need to set the configuration values from the *config/application.yml* file as Heroku environment variables. See the article "Rails Environment Variables":http://railsapps.github.io/rails-environment-variables.html for more information. 352 | 353 | With the figaro gem, just run: 354 | 355 |
356 | rake figaro:heroku 357 |358 | 359 | Alternatively, you can set Heroku environment variables directly with @heroku config:add@. 360 | 361 |
362 | $ heroku config:add GMAIL_USERNAME='myname@gmail.com' GMAIL_PASSWORD='secret' 363 | $ heroku config:add 'ROLES=[admin, user, VIP]' 364 | $ heroku config:add ADMIN_NAME='First User' ADMIN_EMAIL='user@example.com' ADMIN_PASSWORD='changeme' 365 |366 | 367 | Complete Heroku deployment with: 368 | 369 |
370 | $ heroku run rake db:migrate 371 | $ heroku run rake db:seed 372 |373 | 374 | See the "Tutorial for Rails on Heroku":http://railsapps.github.io/rails-heroku-tutorial.html for details. 375 | 376 | h2. Customizing 377 | 378 | This application provides no useful functionality apart from demonstrating Devise with CanCan and Twitter Bootstrap working together on Rails 3. Add any models, controllers, and views that you need. 379 | 380 | For more complex applications that use Devise, CanCan, and Twitter Bootstrap, see: 381 | 382 | * "rails-stripe-membership-saas":http://railsapps.github.io/rails-stripe-membership-saas example and tutorial 383 | * "rails-prelaunch-signup":https://github.com/RailsApps/rails-prelaunch-signup example and tutorial 384 | 385 | h2. Testing 386 | 387 | The example application contains a suite of RSpec unit tests and Cucumber scenarios and step definitions. 388 | 389 | After installing the application, run @rake -T@ to check that rake tasks for RSpec and Cucumber are available. 390 | 391 | Run @rake spec@ to run RSpec tests. 392 | 393 | Run @rake cucumber@ (or more simply, @cucumber@) to run Cucumber scenarios. 394 | 395 | Please send the author a message, create an issue, or submit a pull request if you can contribute improved RSpec or Cucumber files. 396 | 397 | h2. Troubleshooting 398 | 399 | Problems? Check the "issues":https://github.com/RailsApps/rails3-bootstrap-devise-cancan/issues. 400 | 401 | h2. Documentation 402 | 403 | The "tutorial":https://tutorials.railsapps.org/rails3-bootstrap-devise-cancan provides additional documentation. 404 | 405 | For a Devise introduction, Ryan Bates offers a "Railscast on Devise":http://railscasts.com/episodes/209-introducing-devise. You can find documentation for "Devise":https://github.com/plataformatec/devise at "https://github.com/plataformatec/devise":https://github.com/plataformatec/devise. There is an active "Devise mailing list":http://groups.google.com/group/plataformatec-devise and you can submit "Devise issues":https://github.com/plataformatec/devise/issues at GitHub. 406 | 407 | h2. Issues 408 | 409 | Please create a "GitHub issue":https://github.com/RailsApps/rails3-bootstrap-devise-cancan/issues if you identify any problems or have suggestions for improvements. 410 | 411 | h2. Where to Get Help 412 | 413 | Your best source for help with problems is "Stack Overflow":http://stackoverflow.com/questions/tagged/ruby-on-rails-3. Your issue may have been encountered and addressed by others. 414 | 415 | You can also try "Rails Hotline":http://www.railshotline.com/, a free telephone hotline for Rails help staffed by volunteers. 416 | 417 | h2. Contributing 418 | 419 | If you make improvements to this application, please share with others. 420 | 421 | Send the author a message, create an "issue":https://github.com/RailsApps/rails3-bootstrap-devise-cancan/issues, or fork the project and submit a pull request. 422 | 423 | If you add functionality to this application, create an alternative implementation, or build an application that is similar, please contact me and I'll add a note to the README so that others can find your work. 424 | 425 | h2. Credits 426 | 427 | Daniel Kehoe implemented the application and wrote the tutorial. 428 | 429 | Is the app useful to you? Follow the project on Twitter: "@rails_apps":http://twitter.com/rails_apps 430 | and tweet some praise. I'd love to know you were helped out by what I've put together. 431 | 432 | h2. MIT License 433 | 434 | "MIT License":http://www.opensource.org/licenses/mit-license 435 | 436 | Copyright © 2012-13 Daniel Kehoe 437 | 438 | h2. Useful Links 439 | 440 | |_. Getting Started |_. Articles |_. Tutorials | 441 | | "Ruby on Rails":http://railsapps.github.io/ruby-and-rails.html | "Analytics for Rails":http://railsapps.github.io/rails-google-analytics.html | "Rails Bootstrap":http://railsapps.github.io/twitter-bootstrap-rails.html | 442 | | "What is Ruby on Rails?":http://railsapps.github.io/what-is-ruby-rails.html | "Heroku and Rails":http://railsapps.github.io/rails-heroku-tutorial.html | "Rails Foundation":http://railsapps.github.io/rails-foundation.html | 443 | | "Learn Ruby on Rails":http://learn-rails.com/learn-ruby-on-rails.html | "JavaScript and Rails":http://railsapps.github.io/rails-javascript-include-external.html | "RSpec Tutorial":http://railsapps.github.io/rspec.html | 444 | | "Rails Tutorial":https://tutorials.railsapps.org/rails-tutorial | "Rails Environment Variables":http://railsapps.github.io/rails-environment-variables.html | "Rails Devise Tutorial":http://railsapps.github.io/tutorial-rails-devise.html | 445 | | "Ruby on Rails Tutorial for Beginners":http://learn-rails.com/ruby-on-rails-tutorial-for-beginners | "Git and GitHub with Rails":http://railsapps.github.io/rails-git.html | "Devise RSpec":http://railsapps.github.io/tutorial-rails-devise-rspec-cucumber.html | 446 | | "Install Ruby on Rails":http://railsapps.github.io/installing-rails.html | "Send Email with Rails":http://railsapps.github.io/rails-send-email.html | "Devise Bootstrap":http://railsapps.github.io/tutorial-rails-bootstrap-devise-cancan.html | 447 | | "Install Ruby on Rails - Mac OS X":http://railsapps.github.io/installrubyonrails-mac.html | "Haml and Rails":http://railsapps.github.io/rails-haml.html | "Rails Membership Site with Stripe":https://tutorials.railsapps.org/rails-stripe-membership-saas | 448 | | "Install Ruby on Rails - Ubuntu":http://railsapps.github.io/installrubyonrails-ubuntu.html | "Rails Application Layout":http://railsapps.github.io/rails-default-application-layout.html | "Rails Subscription Site with Recurly":https://tutorials.railsapps.org/rails-recurly-subscription-saas | 449 | | "Ruby on Rails - Nitrous.io":http://railsapps.github.io/rubyonrails-nitrous-io.html | "HTML5 Boilerplate for Rails":http://railsapps.github.io/rails-html5-boilerplate.html | "Startup Prelaunch Signup Application":https://tutorials.railsapps.org/rails-prelaunch-signup | 450 | | "Update Rails":http://railsapps.github.io/updating-rails.html | "Example Gemfiles for Rails":http://railsapps.github.io/rails-3-2-example-gemfile.html | 451 | | "Rails Composer":http://railsapps.github.io/rails-composer/ | "Rails Application Templates":http://railsapps.github.io/rails-application-templates.html | 452 | | "Rails Examples":http://railsapps.github.io/ | "Rails Product Planning":http://railsapps.github.io/rails-product-planning.html | 453 | | "Rails Starter Apps":http://railsapps.github.io/rails-examples-tutorials.html | "Rails Project Management":http://railsapps.github.io/rails-project-management.html | 454 | 455 | !https://cruel-carlota.pagodabox.com/face2018e437828af58da43b847d6178(githalytics.com alpha)! 456 | 457 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Rails3BootstrapDeviseCancan::Application.load_tasks 8 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require bootstrap 16 | //= require_tree . 17 | -------------------------------------------------------------------------------- /app/assets/javascripts/home.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | 15 | .content { 16 | background-color: #eee; 17 | padding: 20px; 18 | margin: 0 -20px; /* negative indent the amount of the padding to maintain the grid system */ 19 | -webkit-border-radius: 0 0 6px 6px; 20 | -moz-border-radius: 0 0 6px 6px; 21 | border-radius: 0 0 6px 6px; 22 | -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15); 23 | -moz-box-shadow: 0 1px 2px rgba(0,0,0,.15); 24 | box-shadow: 0 1px 2px rgba(0,0,0,.15); 25 | } 26 | -------------------------------------------------------------------------------- /app/assets/stylesheets/bootstrap_and_overrides.css.scss: -------------------------------------------------------------------------------- 1 | @import "bootstrap"; 2 | body { padding-top: 60px; } 3 | @import "bootstrap-responsive"; 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/home.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | 4 | rescue_from CanCan::AccessDenied do |exception| 5 | redirect_to root_path, :alert => exception.message 6 | end 7 | 8 | end 9 | -------------------------------------------------------------------------------- /app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | @users = User.all 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/users_controller.rb: -------------------------------------------------------------------------------- 1 | class UsersController < ApplicationController 2 | before_filter :authenticate_user! 3 | 4 | def index 5 | authorize! :index, @user, :message => 'Not authorized as an administrator.' 6 | @users = User.all 7 | end 8 | 9 | def show 10 | @user = User.find(params[:id]) 11 | end 12 | 13 | def update 14 | authorize! :update, @user, :message => 'Not authorized as an administrator.' 15 | @user = User.find(params[:id]) 16 | if @user.update_attributes(params[:user], :as => :admin) 17 | redirect_to users_path, :notice => "User updated." 18 | else 19 | redirect_to users_path, :alert => "Unable to update user." 20 | end 21 | end 22 | 23 | def destroy 24 | authorize! :destroy, @user, :message => 'Not authorized as an administrator.' 25 | user = User.find(params[:id]) 26 | unless user == current_user 27 | user.destroy 28 | redirect_to users_path, :notice => "User deleted." 29 | else 30 | redirect_to users_path, :notice => "Can't delete yourself." 31 | end 32 | end 33 | end -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | 3 | def display_base_errors resource 4 | return '' if (resource.errors.empty?) or (resource.errors[:base].empty?) 5 | messages = resource.errors[:base].map { |msg| content_tag(:p, msg) }.join 6 | html = <<-HTML 7 |
Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.
14 | <%= link_to "Back", :back %> 15 | -------------------------------------------------------------------------------- /app/views/devise/registrations/new.html.erb: -------------------------------------------------------------------------------- 1 |User: <%=link_to user.name, user %>
4 | <% end %> 5 | -------------------------------------------------------------------------------- /app/views/layouts/_messages.html.erb: -------------------------------------------------------------------------------- 1 | <% flash.each do |name, msg| %> 2 | <% if msg.is_a?(String) %> 3 |Username | 7 |Registered | 9 |Role | 10 |11 | | 12 | | |
---|---|---|---|---|---|
<%= link_to user.name, user %> | 18 |<%= user.email %> | 19 |<%= user.created_at.to_date %> | 20 |<%= user.roles.first.name.titleize unless user.roles.first.nil? %> | 21 |22 | Change role 23 | <%= render user %> 24 | | 25 |<%= link_to("Delete user", user_path(user), :data => { :confirm => "Are you sure?" }, :method => :delete, :class => 'btn btn-mini') unless user == current_user %> | 26 |
User: <%= @user.name %>
3 |Email: <%= @user.email if @user.email %>
4 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails3BootstrapDeviseCancan::Application 5 | -------------------------------------------------------------------------------- /config/application.example.yml: -------------------------------------------------------------------------------- 1 | # Add account credentials and API keys here. 2 | # See http://railsapps.github.io/rails-environment-variables.html 3 | # This file should be listed in .gitignore to keep your settings secret! 4 | # Each entry sets a local environment variable and overrides ENV variables in the Unix shell. 5 | # For example, setting: 6 | # GMAIL_USERNAME: Your_Gmail_Username 7 | # makes 'Your_Gmail_Username' available as ENV["GMAIL_USERNAME"] 8 | # Add application configuration variables here, as shown below. 9 | # 10 | GMAIL_USERNAME: Your_Username 11 | GMAIL_PASSWORD: Your_Password 12 | ADMIN_NAME: First User 13 | ADMIN_EMAIL: user@example.com 14 | ADMIN_PASSWORD: changeme 15 | ROLES: [admin, user, VIP] 16 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | # Pick the frameworks you want: 4 | require "active_record/railtie" 5 | require "action_controller/railtie" 6 | require "action_mailer/railtie" 7 | require "active_resource/railtie" 8 | require "sprockets/railtie" 9 | # require "rails/test_unit/railtie" 10 | 11 | if defined?(Bundler) 12 | # If you precompile assets before deploying to production, use this line 13 | Bundler.require(*Rails.groups(:assets => %w(development test))) 14 | # If you want your assets lazily compiled in production, use this line 15 | # Bundler.require(:default, :assets, Rails.env) 16 | end 17 | 18 | module Rails3BootstrapDeviseCancan 19 | class Application < Rails::Application 20 | 21 | # don't generate RSpec tests for views and helpers 22 | config.generators do |g| 23 | 24 | g.test_framework :rspec, fixture: true 25 | g.fixture_replacement :factory_girl, dir: 'spec/factories' 26 | 27 | 28 | g.view_specs false 29 | g.helper_specs false 30 | end 31 | 32 | # Settings in config/environments/* take precedence over those specified here. 33 | # Application configuration should go into files in config/initializers 34 | # -- all .rb files in that directory are automatically loaded. 35 | 36 | # Custom directories with classes and modules you want to be autoloadable. 37 | # config.autoload_paths += %W(#{config.root}/extras) 38 | config.autoload_paths += %W(#{config.root}/lib) 39 | 40 | 41 | # Only load the plugins named here, in the order given (default is alphabetical). 42 | # :all can be used as a placeholder for all plugins not explicitly named. 43 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 44 | 45 | # Activate observers that should always be running. 46 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 47 | 48 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 49 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 50 | # config.time_zone = 'Central Time (US & Canada)' 51 | 52 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 53 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 54 | # config.i18n.default_locale = :de 55 | 56 | # Configure the default encoding used in templates for Ruby 1.9. 57 | config.encoding = "utf-8" 58 | 59 | # Configure sensitive parameters which will be filtered from the log file. 60 | config.filter_parameters += [:password, :password_confirmation] 61 | 62 | # Enable escaping HTML in JSON. 63 | config.active_support.escape_html_entities_in_json = true 64 | 65 | # Use SQL instead of Active Record's schema dumper when creating the database. 66 | # This is necessary if your schema can't be completely dumped by the schema dumper, 67 | # like if you have constraints or database-specific column types 68 | # config.active_record.schema_format = :sql 69 | 70 | # Enforce whitelist mode for mass assignment. 71 | # This will create an empty whitelist of attributes available for mass-assignment for all models 72 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible 73 | # parameters by using an attr_accessible or attr_protected declaration. 74 | config.active_record.whitelist_attributes = true 75 | 76 | # Enable the asset pipeline 77 | config.assets.enabled = true 78 | 79 | # Version of your assets, change this if you want to expire all your assets 80 | config.assets.version = '1.0' 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /config/application.yml: -------------------------------------------------------------------------------- 1 | # Add account credentials and API keys here. 2 | # See http://railsapps.github.io/rails-environment-variables.html 3 | # This file should be listed in .gitignore to keep your settings secret! 4 | # Each entry sets a local environment variable and overrides ENV variables in the Unix shell. 5 | # For example, setting: 6 | # GMAIL_USERNAME: Your_Gmail_Username 7 | # makes 'Your_Gmail_Username' available as ENV["GMAIL_USERNAME"] 8 | # Add application configuration variables here, as shown below. 9 | # 10 | GMAIL_USERNAME: Your_Username 11 | GMAIL_PASSWORD: Your_Password 12 | ADMIN_NAME: First User 13 | ADMIN_EMAIL: user@example.com 14 | ADMIN_PASSWORD: changeme 15 | ROLES: [admin, user, VIP] 16 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /config/cucumber.yml: -------------------------------------------------------------------------------- 1 | <% 2 | rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" 3 | rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" 4 | std_opts = "-r features/support/ -r features/step_definitions --format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip" 5 | %> 6 | default: <%= std_opts %> features 7 | wip: --tags @wip:3 --wip features 8 | rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip 9 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: &test 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | 27 | cucumber: 28 | <<: *test -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Rails3BootstrapDeviseCancan::Application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails3BootstrapDeviseCancan::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # ActionMailer Config 17 | config.action_mailer.default_url_options = { :host => 'localhost:3000' } 18 | config.action_mailer.delivery_method = :smtp 19 | # change to true to allow email to be sent during development 20 | config.action_mailer.perform_deliveries = false 21 | config.action_mailer.raise_delivery_errors = true 22 | config.action_mailer.default :charset => "utf-8" 23 | 24 | 25 | # Print deprecation notices to the Rails logger 26 | config.active_support.deprecation = :log 27 | 28 | # Only use best-standards-support built into browsers 29 | config.action_dispatch.best_standards_support = :builtin 30 | 31 | # Raise exception on mass assignment protection for Active Record models 32 | config.active_record.mass_assignment_sanitizer = :strict 33 | 34 | # Log the query plan for queries taking more than this (works 35 | # with SQLite, MySQL, and PostgreSQL) 36 | config.active_record.auto_explain_threshold_in_seconds = 0.5 37 | 38 | # Do not compress assets 39 | config.assets.compress = false 40 | 41 | # Expands the lines which load the assets 42 | config.assets.debug = true 43 | 44 | config.action_mailer.smtp_settings = { 45 | address: "smtp.gmail.com", 46 | port: 587, 47 | domain: ENV["DOMAIN_NAME"], 48 | authentication: "plain", 49 | enable_starttls_auto: true, 50 | user_name: ENV["GMAIL_USERNAME"], 51 | password: ENV["GMAIL_PASSWORD"] 52 | } 53 | 54 | end 55 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails3BootstrapDeviseCancan::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to nil and saved in location specified by config.assets.prefix 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Prepend all log lines with the following tags 37 | # config.log_tags = [ :subdomain, :uuid ] 38 | 39 | # Use a different logger for distributed setups 40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 41 | 42 | # Use a different cache store in production 43 | # config.cache_store = :mem_cache_store 44 | 45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 46 | # config.action_controller.asset_host = "http://assets.example.com" 47 | 48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 49 | # config.assets.precompile += %w( search.js ) 50 | 51 | # Disable delivery errors, bad email addresses will be ignored 52 | # config.action_mailer.raise_delivery_errors = false 53 | 54 | # Enable threaded mode 55 | # config.threadsafe! 56 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 58 | # the I18n.default_locale when a translation can not be found) 59 | config.i18n.fallbacks = true 60 | 61 | # Send deprecation notices to registered listeners 62 | config.active_support.deprecation = :notify 63 | 64 | config.action_mailer.smtp_settings = { 65 | address: "smtp.gmail.com", 66 | port: 587, 67 | domain: ENV["DOMAIN_NAME"], 68 | authentication: "plain", 69 | enable_starttls_auto: true, 70 | user_name: ENV["GMAIL_USERNAME"], 71 | password: ENV["GMAIL_PASSWORD"] 72 | } 73 | 74 | 75 | config.action_mailer.default_url_options = { :host => 'example.com' } 76 | # ActionMailer Config 77 | # Setup for production - deliveries, no errors raised 78 | config.action_mailer.delivery_method = :smtp 79 | config.action_mailer.perform_deliveries = true 80 | config.action_mailer.raise_delivery_errors = false 81 | config.action_mailer.default :charset => "utf-8" 82 | 83 | 84 | # Log the query plan for queries taking more than this (works 85 | # with SQLite, MySQL, and PostgreSQL) 86 | # config.active_record.auto_explain_threshold_in_seconds = 0.5 87 | end 88 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails3BootstrapDeviseCancan::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 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | 38 | # ActionMailer Config 39 | config.action_mailer.default_url_options = { :host => 'example.com' } 40 | 41 | end 42 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/devise.rb: -------------------------------------------------------------------------------- 1 | # Use this hook to configure devise mailer, warden hooks and so forth. 2 | # Many of these configuration options can be set straight in your model. 3 | Devise.setup do |config| 4 | # ==> Mailer Configuration 5 | # Configure the e-mail address which will be shown in Devise::Mailer, 6 | # note that it will be overwritten if you use your own mailer class with default "from" parameter. 7 | config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com" 8 | 9 | # Configure the class responsible to send e-mails. 10 | # config.mailer = "Devise::Mailer" 11 | 12 | # ==> ORM configuration 13 | # Load and configure the ORM. Supports :active_record (default) and 14 | # :mongoid (bson_ext recommended) by default. Other ORMs may be 15 | # available as additional gems. 16 | require 'devise/orm/active_record' 17 | 18 | # ==> Configuration for any authentication mechanism 19 | # Configure which keys are used when authenticating a user. The default is 20 | # just :email. You can configure it to use [:username, :subdomain], so for 21 | # authenticating a user, both parameters are required. Remember that those 22 | # parameters are used only when authenticating and not when retrieving from 23 | # session. If you need permissions, you should implement that in a before filter. 24 | # You can also supply a hash where the value is a boolean determining whether 25 | # or not authentication should be aborted when the value is not present. 26 | # config.authentication_keys = [ :email ] 27 | 28 | # Configure parameters from the request object used for authentication. Each entry 29 | # given should be a request method and it will automatically be passed to the 30 | # find_for_authentication method and considered in your model lookup. For instance, 31 | # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. 32 | # The same considerations mentioned for authentication_keys also apply to request_keys. 33 | # config.request_keys = [] 34 | 35 | # Configure which authentication keys should be case-insensitive. 36 | # These keys will be downcased upon creating or modifying a user and when used 37 | # to authenticate or find a user. Default is :email. 38 | config.case_insensitive_keys = [ :email ] 39 | 40 | # Configure which authentication keys should have whitespace stripped. 41 | # These keys will have whitespace before and after removed upon creating or 42 | # modifying a user and when used to authenticate or find a user. Default is :email. 43 | config.strip_whitespace_keys = [ :email ] 44 | 45 | # Tell if authentication through request.params is enabled. True by default. 46 | # It can be set to an array that will enable params authentication only for the 47 | # given strategies, for example, `config.params_authenticatable = [:database]` will 48 | # enable it only for database (email + password) authentication. 49 | # config.params_authenticatable = true 50 | 51 | # Tell if authentication through HTTP Auth is enabled. False by default. 52 | # It can be set to an array that will enable http authentication only for the 53 | # given strategies, for example, `config.http_authenticatable = [:token]` will 54 | # enable it only for token authentication. The supported strategies are: 55 | # :database = Support basic authentication with authentication key + password 56 | # :token = Support basic authentication with token authentication key 57 | # :token_options = Support token authentication with options as defined in 58 | # http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html 59 | # config.http_authenticatable = false 60 | 61 | # If http headers should be returned for AJAX requests. True by default. 62 | # config.http_authenticatable_on_xhr = true 63 | 64 | # The realm used in Http Basic Authentication. "Application" by default. 65 | # config.http_authentication_realm = "Application" 66 | 67 | # It will change confirmation, password recovery and other workflows 68 | # to behave the same regardless if the e-mail provided was right or wrong. 69 | # Does not affect registerable. 70 | # config.paranoid = true 71 | 72 | # By default Devise will store the user in session. You can skip storage for 73 | # :http_auth and :token_auth by adding those symbols to the array below. 74 | # Notice that if you are skipping storage for all authentication paths, you 75 | # may want to disable generating routes to Devise's sessions controller by 76 | # passing :skip => :sessions to `devise_for` in your config/routes.rb 77 | config.skip_session_storage = [:http_auth] 78 | 79 | # By default, Devise cleans up the CSRF token on authentication to 80 | # avoid CSRF token fixation attacks. This means that, when using AJAX 81 | # requests for sign in and sign up, you need to get a new CSRF token 82 | # from the server. You can disable this option at your own risk. 83 | # config.clean_up_csrf_token_on_authentication = true 84 | 85 | # ==> Configuration for :database_authenticatable 86 | # For bcrypt, this is the cost for hashing the password and defaults to 10. If 87 | # using other encryptors, it sets how many times you want the password re-encrypted. 88 | # 89 | # Limiting the stretches to just one in testing will increase the performance of 90 | # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use 91 | # a value less than 10 in other environments. 92 | config.stretches = Rails.env.test? ? 1 : 10 93 | 94 | # Setup a pepper to generate the encrypted password. 95 | # config.pepper = "b5d1ccb65f0d488f2e20b7519ab4b6a363b2286760fb997ac4d3f13e3b91e0755e8921c8663ccd2ce016d6dc85a120ce990f245ace731d0f672bf5a8098da21c" 96 | 97 | # ==> Configuration for :confirmable 98 | # A period that the user is allowed to access the website even without 99 | # confirming his account. For instance, if set to 2.days, the user will be 100 | # able to access the website for two days without confirming his account, 101 | # access will be blocked just in the third day. Default is 0.days, meaning 102 | # the user cannot access the website without confirming his account. 103 | # config.allow_unconfirmed_access_for = 2.days 104 | 105 | # A period that the user is allowed to confirm their account before their 106 | # token becomes invalid. For example, if set to 3.days, the user can confirm 107 | # their account within 3 days after the mail was sent, but on the fourth day 108 | # their account can't be confirmed with the token any more. 109 | # Default is nil, meaning there is no restriction on how long a user can take 110 | # before confirming their account. 111 | # config.confirm_within = 3.days 112 | 113 | # If true, requires any email changes to be confirmed (exactly the same way as 114 | # initial account confirmation) to be applied. Requires additional unconfirmed_email 115 | # db field (see migrations). Until confirmed new email is stored in 116 | # unconfirmed email column, and copied to email column on successful confirmation. 117 | config.reconfirmable = true 118 | 119 | # Defines which key will be used when confirming an account 120 | # config.confirmation_keys = [ :email ] 121 | 122 | # ==> Configuration for :rememberable 123 | # The time the user will be remembered without asking for credentials again. 124 | # config.remember_for = 2.weeks 125 | 126 | # If true, extends the user's remember period when remembered via cookie. 127 | # config.extend_remember_period = false 128 | 129 | # Options to be passed to the created cookie. For instance, you can set 130 | # :secure => true in order to force SSL only cookies. 131 | # config.rememberable_options = {} 132 | 133 | # ==> Configuration for :validatable 134 | # Range for password length. Default is 8..128. 135 | config.password_length = 8..128 136 | 137 | # Email regex used to validate email formats. It simply asserts that 138 | # one (and only one) @ exists in the given string. This is mainly 139 | # to give user feedback and not to assert the e-mail validity. 140 | # config.email_regexp = /\A[^@]+@[^@]+\z/ 141 | 142 | # ==> Configuration for :timeoutable 143 | # The time you want to timeout the user session without activity. After this 144 | # time the user will be asked for credentials again. Default is 30 minutes. 145 | # config.timeout_in = 30.minutes 146 | 147 | # If true, expires auth token on session timeout. 148 | # config.expire_auth_token_on_timeout = false 149 | 150 | # ==> Configuration for :lockable 151 | # Defines which strategy will be used to lock an account. 152 | # :failed_attempts = Locks an account after a number of failed attempts to sign in. 153 | # :none = No lock strategy. You should handle locking by yourself. 154 | # config.lock_strategy = :failed_attempts 155 | 156 | # Defines which key will be used when locking and unlocking an account 157 | # config.unlock_keys = [ :email ] 158 | 159 | # Defines which strategy will be used to unlock an account. 160 | # :email = Sends an unlock link to the user email 161 | # :time = Re-enables login after a certain amount of time (see :unlock_in below) 162 | # :both = Enables both strategies 163 | # :none = No unlock strategy. You should handle unlocking by yourself. 164 | # config.unlock_strategy = :both 165 | 166 | # Number of authentication tries before locking an account if lock_strategy 167 | # is failed attempts. 168 | # config.maximum_attempts = 20 169 | 170 | # Time interval to unlock the account if :time is enabled as unlock_strategy. 171 | # config.unlock_in = 1.hour 172 | 173 | # ==> Configuration for :recoverable 174 | # 175 | # Defines which key will be used when recovering the password for an account 176 | # config.reset_password_keys = [ :email ] 177 | 178 | # Time interval you can reset your password with a reset password key. 179 | # Don't put a too small interval or your users won't have the time to 180 | # change their passwords. 181 | config.reset_password_within = 6.hours 182 | 183 | # ==> Configuration for :encryptable 184 | # Allow you to use another encryption algorithm besides bcrypt (default). You can use 185 | # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, 186 | # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) 187 | # and :restful_authentication_sha1 (then you should set stretches to 10, and copy 188 | # REST_AUTH_SITE_KEY to pepper). 189 | # 190 | # Require the `devise-encryptable` gem when using anything other than bcrypt 191 | # config.encryptor = :sha512 192 | 193 | # ==> Configuration for :token_authenticatable 194 | # Defines name of the authentication token params key 195 | # config.token_authentication_key = :auth_token 196 | 197 | # ==> Scopes configuration 198 | # Turn scoped views on. Before rendering "sessions/new", it will first check for 199 | # "users/sessions/new". It's turned off by default because it's slower if you 200 | # are using only default views. 201 | # config.scoped_views = false 202 | 203 | # Configure the default scope given to Warden. By default it's the first 204 | # devise role declared in your routes (usually :user). 205 | # config.default_scope = :user 206 | 207 | # Set this configuration to false if you want /users/sign_out to sign out 208 | # only the current scope. By default, Devise signs out all scopes. 209 | # config.sign_out_all_scopes = true 210 | 211 | # ==> Navigation configuration 212 | # Lists the formats that should be treated as navigational. Formats like 213 | # :html, should redirect to the sign in page when the user does not have 214 | # access, but formats like :xml or :json, should return 401. 215 | # 216 | # If you have any extra navigational formats, like :iphone or :mobile, you 217 | # should add them to the navigational formats lists. 218 | # 219 | # The "*/*" below is required to match Internet Explorer requests. 220 | # config.navigational_formats = ["*/*", :html] 221 | 222 | # The default HTTP method used to sign out a resource. Default is :delete. 223 | config.sign_out_via = Rails.env.test? ? :get : :delete 224 | 225 | # ==> OmniAuth 226 | # Add a new OmniAuth provider. Check the wiki for more information on setting 227 | # up on your models and hooks. 228 | # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo' 229 | 230 | # ==> Warden configuration 231 | # If you want to use other strategies, that are not supported by Devise, or 232 | # change the failure app, you can configure them inside the config.warden block. 233 | # 234 | # config.warden do |manager| 235 | # manager.intercept_401 = false 236 | # manager.default_strategies(:scope => :user).unshift :some_external_strategy 237 | # end 238 | 239 | # ==> Mountable engine configurations 240 | # When using Devise inside an engine, let's call it `MyEngine`, and this engine 241 | # is mountable, there are some extra configurations to be taken into account. 242 | # The following options are available, assuming the engine is mounted as: 243 | # 244 | # mount MyEngine, at: "/my_engine" 245 | # 246 | # The router that invoked `devise_for`, in the example above, would be: 247 | # config.router_name = :my_engine 248 | # 249 | # When using omniauth, Devise cannot automatically set Omniauth path, 250 | # so you need to do it manually. For the users scope, it would be: 251 | # config.omniauth_path_prefix = "/my_engine/users/auth" 252 | end 253 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /config/initializers/rolify.rb: -------------------------------------------------------------------------------- 1 | Rolify.configure do |config| 2 | # By default ORM adapter is ActiveRecord. uncomment to use mongoid 3 | # config.use_mongoid 4 | 5 | # Dynamic shortcuts for User class (user.is_admin? like methods). Default is: false 6 | # Enable this feature _after_ running rake db:migrate as it relies on the roles table 7 | # config.use_dynamic_shortcuts 8 | end -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Rails3BootstrapDeviseCancan::Application.config.secret_token = 'a6cd68af2c0c93e2f0bd4c576aab509f59b7ae839d02018caa4c8ce3cc46ea012fdc4f1dc93bbb14137bc646fb697907e9649260d02b77eed838717d20dff479' 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails3BootstrapDeviseCancan::Application.config.session_store :cookie_store, key: '_rails3-bootstrap-devise-cancan_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Rails3BootstrapDeviseCancan::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /config/initializers/simple_form.rb: -------------------------------------------------------------------------------- 1 | # Use this setup block to configure all options available in SimpleForm. 2 | SimpleForm.setup do |config| 3 | # Wrappers are used by the form builder to generate a 4 | # complete input. You can remove any component from the 5 | # wrapper, change the order or even add your own to the 6 | # stack. The options given below are used to wrap the 7 | # whole input. 8 | config.wrappers :default, :class => :input, 9 | :hint_class => :field_with_hint, :error_class => :field_with_errors do |b| 10 | ## Extensions enabled by default 11 | # Any of these extensions can be disabled for a 12 | # given input by passing: `f.input EXTENSION_NAME => false`. 13 | # You can make any of these extensions optional by 14 | # renaming `b.use` to `b.optional`. 15 | 16 | # Determines whether to use HTML5 (:email, :url, ...) 17 | # and required attributes 18 | b.use :html5 19 | 20 | # Calculates placeholders automatically from I18n 21 | # You can also pass a string as f.input :placeholder => "Placeholder" 22 | b.use :placeholder 23 | 24 | ## Optional extensions 25 | # They are disabled unless you pass `f.input EXTENSION_NAME => :lookup` 26 | # to the input. If so, they will retrieve the values from the model 27 | # if any exists. If you want to enable the lookup for any of those 28 | # extensions by default, you can change `b.optional` to `b.use`. 29 | 30 | # Calculates maxlength from length validations for string inputs 31 | b.optional :maxlength 32 | 33 | # Calculates pattern from format validations for string inputs 34 | b.optional :pattern 35 | 36 | # Calculates min and max from length validations for numeric inputs 37 | b.optional :min_max 38 | 39 | # Calculates readonly automatically from readonly attributes 40 | b.optional :readonly 41 | 42 | ## Inputs 43 | b.use :label_input 44 | b.use :hint, :wrap_with => { :tag => :span, :class => :hint } 45 | b.use :error, :wrap_with => { :tag => :span, :class => :error } 46 | end 47 | 48 | # The default wrapper to be used by the FormBuilder. 49 | config.default_wrapper = :default 50 | 51 | # Define the way to render check boxes / radio buttons with labels. 52 | # Defaults to :nested for bootstrap config. 53 | # :inline => input + label 54 | # :nested => label > input 55 | config.boolean_style = :nested 56 | 57 | # Default class for buttons 58 | config.button_class = 'btn' 59 | 60 | # Method used to tidy up errors. Specify any Rails Array method. 61 | # :first lists the first message for each field. 62 | # Use :to_sentence to list all errors for each field. 63 | # config.error_method = :first 64 | 65 | # Default tag used for error notification helper. 66 | config.error_notification_tag = :div 67 | 68 | # CSS class to add for error notification helper. 69 | config.error_notification_class = 'alert alert-error' 70 | 71 | # ID to add for error notification helper. 72 | # config.error_notification_id = nil 73 | 74 | # Series of attempts to detect a default label method for collection. 75 | # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] 76 | 77 | # Series of attempts to detect a default value method for collection. 78 | # config.collection_value_methods = [ :id, :to_s ] 79 | 80 | # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. 81 | # config.collection_wrapper_tag = nil 82 | 83 | # You can define the class to use on all collection wrappers. Defaulting to none. 84 | # config.collection_wrapper_class = nil 85 | 86 | # You can wrap each item in a collection of radio/check boxes with a tag, 87 | # defaulting to :span. Please note that when using :boolean_style = :nested, 88 | # SimpleForm will force this option to be a label. 89 | # config.item_wrapper_tag = :span 90 | 91 | # You can define a class to use in all item wrappers. Defaulting to none. 92 | # config.item_wrapper_class = nil 93 | 94 | # How the label text should be generated altogether with the required text. 95 | # config.label_text = lambda { |label, required| "#{required} #{label}" } 96 | 97 | # You can define the class to use on all labels. Default is nil. 98 | config.label_class = 'control-label' 99 | 100 | # You can define the class to use on all forms. Default is simple_form. 101 | # config.form_class = :simple_form 102 | 103 | # You can define which elements should obtain additional classes 104 | # config.generate_additional_classes_for = [:wrapper, :label, :input] 105 | 106 | # Whether attributes are required by default (or not). Default is true. 107 | # config.required_by_default = true 108 | 109 | # Tell browsers whether to use default HTML5 validations (novalidate option). 110 | # Default is enabled. 111 | config.browser_validations = false 112 | 113 | # Collection of methods to detect if a file type was given. 114 | # config.file_methods = [ :mounted_as, :file?, :public_filename ] 115 | 116 | # Custom mappings for input types. This should be a hash containing a regexp 117 | # to match as key, and the input type that will be used when the field name 118 | # matches the regexp as value. 119 | # config.input_mappings = { /count/ => :integer } 120 | 121 | # Custom wrappers for input types. This should be a hash containing an input 122 | # type as key and the wrapper that will be used for all inputs with specified type. 123 | # config.wrapper_mappings = { :string => :prepend } 124 | 125 | # Default priority for time_zone inputs. 126 | # config.time_zone_priority = nil 127 | 128 | # Default priority for country inputs. 129 | # config.country_priority = nil 130 | 131 | # Default size for text inputs. 132 | # config.default_input_size = 50 133 | 134 | # When false, do not use translations for labels. 135 | # config.translate_labels = true 136 | 137 | # Automatically discover new inputs in Rails' autoload path. 138 | # config.inputs_discovery = true 139 | 140 | # Cache SimpleForm inputs discovery 141 | # config.cache_discovery = !Rails.env.development? 142 | end 143 | -------------------------------------------------------------------------------- /config/initializers/simple_form_bootstrap.rb: -------------------------------------------------------------------------------- 1 | # Use this setup block to configure all options available in SimpleForm. 2 | SimpleForm.setup do |config| 3 | config.wrappers :bootstrap, :tag => 'div', :class => 'control-group', :error_class => 'error' do |b| 4 | b.use :html5 5 | b.use :placeholder 6 | b.use :label 7 | b.wrapper :tag => 'div', :class => 'controls' do |ba| 8 | ba.use :input 9 | ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } 10 | ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' } 11 | end 12 | end 13 | 14 | config.wrappers :prepend, :tag => 'div', :class => "control-group", :error_class => 'error' do |b| 15 | b.use :html5 16 | b.use :placeholder 17 | b.use :label 18 | b.wrapper :tag => 'div', :class => 'controls' do |input| 19 | input.wrapper :tag => 'div', :class => 'input-prepend' do |prepend| 20 | prepend.use :input 21 | end 22 | input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' } 23 | input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } 24 | end 25 | end 26 | 27 | config.wrappers :append, :tag => 'div', :class => "control-group", :error_class => 'error' do |b| 28 | b.use :html5 29 | b.use :placeholder 30 | b.use :label 31 | b.wrapper :tag => 'div', :class => 'controls' do |input| 32 | input.wrapper :tag => 'div', :class => 'input-append' do |append| 33 | append.use :input 34 | end 35 | input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' } 36 | input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } 37 | end 38 | end 39 | 40 | # Wrappers for forms and inputs using the Twitter Bootstrap toolkit. 41 | # Check the Bootstrap docs (http://twitter.github.com/bootstrap) 42 | # to learn about the different styles for forms and inputs, 43 | # buttons and other elements. 44 | config.default_wrapper = :bootstrap 45 | end 46 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /config/locales/devise.en.yml: -------------------------------------------------------------------------------- 1 | # Additional translations at https://github.com/plataformatec/devise/wiki/I18n 2 | 3 | en: 4 | devise: 5 | confirmations: 6 | confirmed: "Your account was successfully confirmed. You are now signed in." 7 | send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." 8 | send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes." 9 | failure: 10 | already_authenticated: "You are already signed in." 11 | inactive: "Your account was not activated yet." 12 | invalid: "Invalid email or password." 13 | invalid_token: "Invalid authentication token." 14 | locked: "Your account is locked." 15 | not_found_in_database: "Invalid email or password." 16 | timeout: "Your session expired, please sign in again to continue." 17 | unauthenticated: "You need to sign in or sign up before continuing." 18 | unconfirmed: "You have to confirm your account before continuing." 19 | mailer: 20 | confirmation_instructions: 21 | subject: "Confirmation instructions" 22 | reset_password_instructions: 23 | subject: "Reset password instructions" 24 | unlock_instructions: 25 | subject: "Unlock Instructions" 26 | omniauth_callbacks: 27 | failure: "Could not authenticate you from %{kind} because \"%{reason}\"." 28 | success: "Successfully authenticated from %{kind} account." 29 | passwords: 30 | no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." 31 | send_instructions: "You will receive an email with instructions about how to reset your password in a few minutes." 32 | send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." 33 | updated: "Your password was changed successfully. You are now signed in." 34 | updated_not_active: "Your password was changed successfully." 35 | registrations: 36 | destroyed: "Bye! Your account was successfully cancelled. We hope to see you again soon." 37 | signed_up: "Welcome! You have signed up successfully." 38 | signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." 39 | signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." 40 | signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account." 41 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address." 42 | updated: "You updated your account successfully." 43 | sessions: 44 | signed_in: "Signed in successfully." 45 | signed_out: "Signed out successfully." 46 | unlocks: 47 | send_instructions: "You will receive an email with instructions about how to unlock your account in a few minutes." 48 | send_paranoid_instructions: "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes." 49 | unlocked: "Your account has been unlocked successfully. Please sign in to continue." 50 | errors: 51 | messages: 52 | already_confirmed: "was already confirmed, please try signing in" 53 | confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" 54 | expired: "has expired, please request a new one" 55 | not_found: "not found" 56 | not_locked: "was not locked" 57 | not_saved: 58 | one: "1 error prohibited this %{resource} from being saved:" 59 | other: "%{count} errors prohibited this %{resource} from being saved:" 60 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /config/locales/simple_form.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | simple_form: 3 | "yes": 'Yes' 4 | "no": 'No' 5 | required: 6 | text: 'required' 7 | mark: '*' 8 | # You can uncomment the line below if you need to overwrite the whole required html. 9 | # When using html, text and mark won't be used. 10 | # html: '*' 11 | error_notification: 12 | default_message: "Please review the problems below:" 13 | # Labels and hints examples 14 | # labels: 15 | # defaults: 16 | # password: 'Password' 17 | # user: 18 | # new: 19 | # email: 'E-mail to sign in.' 20 | # edit: 21 | # email: 'E-mail.' 22 | # hints: 23 | # defaults: 24 | # username: 'User name to sign in.' 25 | # password: 'No special characters, please.' 26 | 27 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails3BootstrapDeviseCancan::Application.routes.draw do 2 | authenticated :user do 3 | root :to => 'home#index' 4 | end 5 | root :to => "home#index" 6 | devise_for :users 7 | resources :users 8 | end -------------------------------------------------------------------------------- /db/migrate/20120418171104_devise_create_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table(:users) do |t| 4 | ## Database authenticatable 5 | t.string :email, :null => false, :default => "" 6 | t.string :encrypted_password, :null => false, :default => "" 7 | 8 | ## Recoverable 9 | t.string :reset_password_token 10 | t.datetime :reset_password_sent_at 11 | 12 | ## Rememberable 13 | t.datetime :remember_created_at 14 | 15 | ## Trackable 16 | t.integer :sign_in_count, :default => 0 17 | t.datetime :current_sign_in_at 18 | t.datetime :last_sign_in_at 19 | t.string :current_sign_in_ip 20 | t.string :last_sign_in_ip 21 | 22 | ## Encryptable 23 | # t.string :password_salt 24 | 25 | ## Confirmable 26 | # t.string :confirmation_token 27 | # t.datetime :confirmed_at 28 | # t.datetime :confirmation_sent_at 29 | # t.string :unconfirmed_email # Only if using reconfirmable 30 | 31 | ## Lockable 32 | # t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts 33 | # t.string :unlock_token # Only if unlock strategy is :email or :both 34 | # t.datetime :locked_at 35 | 36 | ## Token authenticatable 37 | # t.string :authentication_token 38 | 39 | 40 | t.timestamps 41 | end 42 | 43 | add_index :users, :email, :unique => true 44 | add_index :users, :reset_password_token, :unique => true 45 | # add_index :users, :confirmation_token, :unique => true 46 | # add_index :users, :unlock_token, :unique => true 47 | # add_index :users, :authentication_token, :unique => true 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /db/migrate/20120418171110_rolify_create_roles.rb: -------------------------------------------------------------------------------- 1 | class RolifyCreateRoles < ActiveRecord::Migration 2 | def change 3 | create_table(:roles) do |t| 4 | t.string :name 5 | t.references :resource, :polymorphic => true 6 | 7 | t.timestamps 8 | end 9 | 10 | create_table(:users_roles, :id => false) do |t| 11 | t.references :user 12 | t.references :role 13 | end 14 | 15 | add_index(:roles, :name) 16 | add_index(:roles, [ :name, :resource_type, :resource_id ]) 17 | add_index(:users_roles, [ :user_id, :role_id ]) 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /db/migrate/20120418171112_add_name_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddNameToUsers < ActiveRecord::Migration 2 | def change 3 | add_column :users, :name, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20120418171112) do 15 | 16 | create_table "roles", :force => true do |t| 17 | t.string "name" 18 | t.integer "resource_id" 19 | t.string "resource_type" 20 | t.datetime "created_at", :null => false 21 | t.datetime "updated_at", :null => false 22 | end 23 | 24 | add_index "roles", ["name", "resource_type", "resource_id"], :name => "index_roles_on_name_and_resource_type_and_resource_id" 25 | add_index "roles", ["name"], :name => "index_roles_on_name" 26 | 27 | create_table "users", :force => true do |t| 28 | t.string "email", :default => "", :null => false 29 | t.string "encrypted_password", :default => "", :null => false 30 | t.string "reset_password_token" 31 | t.datetime "reset_password_sent_at" 32 | t.datetime "remember_created_at" 33 | t.integer "sign_in_count", :default => 0 34 | t.datetime "current_sign_in_at" 35 | t.datetime "last_sign_in_at" 36 | t.string "current_sign_in_ip" 37 | t.string "last_sign_in_ip" 38 | t.datetime "created_at", :null => false 39 | t.datetime "updated_at", :null => false 40 | t.string "name" 41 | end 42 | 43 | add_index "users", ["email"], :name => "index_users_on_email", :unique => true 44 | add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true 45 | 46 | create_table "users_roles", :id => false, :force => true do |t| 47 | t.integer "user_id" 48 | t.integer "role_id" 49 | end 50 | 51 | add_index "users_roles", ["user_id", "role_id"], :name => "index_users_roles_on_user_id_and_role_id" 52 | 53 | end 54 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | # Environment variables (ENV['...']) can be set in the file config/application.yml. 9 | # See http://railsapps.github.io/rails-environment-variables.html 10 | puts 'ROLES' 11 | YAML.load(ENV['ROLES']).each do |role| 12 | Role.find_or_create_by_name({ :name => role }, :without_protection => true) 13 | puts 'role: ' << role 14 | end 15 | puts 'DEFAULT USERS' 16 | user = User.find_or_create_by_email :name => ENV['ADMIN_NAME'].dup, :email => ENV['ADMIN_EMAIL'].dup, :password => ENV['ADMIN_PASSWORD'].dup, :password_confirmation => ENV['ADMIN_PASSWORD'].dup 17 | puts 'user: ' << user.name 18 | user.add_role :admin -------------------------------------------------------------------------------- /features/step_definitions/email_steps.rb: -------------------------------------------------------------------------------- 1 | # Commonly used email steps 2 | # 3 | # To add your own steps make a custom_email_steps.rb 4 | # The provided methods are: 5 | # 6 | # last_email_address 7 | # reset_mailer 8 | # open_last_email 9 | # visit_in_email 10 | # unread_emails_for 11 | # mailbox_for 12 | # current_email 13 | # open_email 14 | # read_emails_for 15 | # find_email 16 | # 17 | # General form for email scenarios are: 18 | # - clear the email queue (done automatically by email_spec) 19 | # - execute steps that sends an email 20 | # - check the user received an/no/[0-9] emails 21 | # - open the email 22 | # - inspect the email contents 23 | # - interact with the email (e.g. click links) 24 | # 25 | # The Cucumber steps below are setup in this order. 26 | 27 | module EmailHelpers 28 | def current_email_address 29 | # Replace with your a way to find your current email. e.g @current_user.email 30 | # last_email_address will return the last email address used by email spec to find an email. 31 | # Note that last_email_address will be reset after each Scenario. 32 | last_email_address || "example@example.com" 33 | end 34 | end 35 | 36 | World(EmailHelpers) 37 | 38 | # 39 | # Reset the e-mail queue within a scenario. 40 | # This is done automatically before each scenario. 41 | # 42 | 43 | Given /^(?:a clear email queue|no emails have been sent)$/ do 44 | reset_mailer 45 | end 46 | 47 | # 48 | # Check how many emails have been sent/received 49 | # 50 | 51 | Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount| 52 | unread_emails_for(address).size.should == parse_email_count(amount) 53 | end 54 | 55 | Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |address, amount| 56 | mailbox_for(address).size.should == parse_email_count(amount) 57 | end 58 | 59 | Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject "([^"]*?)"$/ do |address, amount, subject| 60 | unread_emails_for(address).select { |m| m.subject =~ Regexp.new(Regexp.escape(subject)) }.size.should == parse_email_count(amount) 61 | end 62 | 63 | Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject \/([^"]*?)\/$/ do |address, amount, subject| 64 | unread_emails_for(address).select { |m| m.subject =~ Regexp.new(subject) }.size.should == parse_email_count(amount) 65 | end 66 | 67 | Then /^(?:I|they|"([^"]*?)") should receive an email with the following body:$/ do |address, expected_body| 68 | open_email(address, :with_text => expected_body) 69 | end 70 | 71 | # 72 | # Accessing emails 73 | # 74 | 75 | # Opens the most recently received email 76 | When /^(?:I|they|"([^"]*?)") opens? the email$/ do |address| 77 | open_email(address) 78 | end 79 | 80 | When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |address, subject| 81 | open_email(address, :with_subject => subject) 82 | end 83 | 84 | When /^(?:I|they|"([^"]*?)") opens? the email with subject \/([^"]*?)\/$/ do |address, subject| 85 | open_email(address, :with_subject => Regexp.new(subject)) 86 | end 87 | 88 | When /^(?:I|they|"([^"]*?)") opens? the email with text "([^"]*?)"$/ do |address, text| 89 | open_email(address, :with_text => text) 90 | end 91 | 92 | When /^(?:I|they|"([^"]*?)") opens? the email with text \/([^"]*?)\/$/ do |address, text| 93 | open_email(address, :with_text => Regexp.new(text)) 94 | end 95 | 96 | # 97 | # Inspect the Email Contents 98 | # 99 | 100 | Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text| 101 | current_email.should have_subject(text) 102 | end 103 | 104 | Then /^(?:I|they) should see \/([^"]*?)\/ in the email subject$/ do |text| 105 | current_email.should have_subject(Regexp.new(text)) 106 | end 107 | 108 | Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text| 109 | current_email.default_part_body.to_s.should include(text) 110 | end 111 | 112 | Then /^(?:I|they) should see \/([^"]*?)\/ in the email body$/ do |text| 113 | current_email.default_part_body.to_s.should =~ Regexp.new(text) 114 | end 115 | 116 | Then /^(?:I|they) should see the email delivered from "([^"]*?)"$/ do |text| 117 | current_email.should be_delivered_from(text) 118 | end 119 | 120 | Then /^(?:I|they) should see "([^\"]*)" in the email "([^"]*?)" header$/ do |text, name| 121 | current_email.should have_header(name, text) 122 | end 123 | 124 | Then /^(?:I|they) should see \/([^\"]*)\/ in the email "([^"]*?)" header$/ do |text, name| 125 | current_email.should have_header(name, Regexp.new(text)) 126 | end 127 | 128 | Then /^I should see it is a multi\-part email$/ do 129 | current_email.should be_multipart 130 | end 131 | 132 | Then /^(?:I|they) should see "([^"]*?)" in the email html part body$/ do |text| 133 | current_email.html_part.body.to_s.should include(text) 134 | end 135 | 136 | Then /^(?:I|they) should see "([^"]*?)" in the email text part body$/ do |text| 137 | current_email.text_part.body.to_s.should include(text) 138 | end 139 | 140 | # 141 | # Inspect the Email Attachments 142 | # 143 | 144 | Then /^(?:I|they) should see (an|no|\d+) attachments? with the email$/ do |amount| 145 | current_email_attachments.size.should == parse_email_count(amount) 146 | end 147 | 148 | Then /^there should be (an|no|\d+) attachments? named "([^"]*?)"$/ do |amount, filename| 149 | current_email_attachments.select { |a| a.filename == filename }.size.should == parse_email_count(amount) 150 | end 151 | 152 | Then /^attachment (\d+) should be named "([^"]*?)"$/ do |index, filename| 153 | current_email_attachments[(index.to_i - 1)].filename.should == filename 154 | end 155 | 156 | Then /^there should be (an|no|\d+) attachments? of type "([^"]*?)"$/ do |amount, content_type| 157 | current_email_attachments.select { |a| a.content_type.include?(content_type) }.size.should == parse_email_count(amount) 158 | end 159 | 160 | Then /^attachment (\d+) should be of type "([^"]*?)"$/ do |index, content_type| 161 | current_email_attachments[(index.to_i - 1)].content_type.should include(content_type) 162 | end 163 | 164 | Then /^all attachments should not be blank$/ do 165 | current_email_attachments.each do |attachment| 166 | attachment.read.size.should_not == 0 167 | end 168 | end 169 | 170 | Then /^show me a list of email attachments$/ do 171 | EmailSpec::EmailViewer::save_and_open_email_attachments_list(current_email) 172 | end 173 | 174 | # 175 | # Interact with Email Contents 176 | # 177 | 178 | When /^(?:I|they|"([^"]*?)") follows? "([^"]*?)" in the email$/ do |address, link| 179 | visit_in_email(link, address) 180 | end 181 | 182 | When /^(?:I|they) click the first link in the email$/ do 183 | click_first_link_in_email 184 | end 185 | 186 | # 187 | # Debugging 188 | # These only work with Rails and OSx ATM since EmailViewer uses RAILS_ROOT and OSx's 'open' command. 189 | # Patches accepted. ;) 190 | # 191 | 192 | Then /^save and open current email$/ do 193 | EmailSpec::EmailViewer::save_and_open_email(current_email) 194 | end 195 | 196 | Then /^save and open all text emails$/ do 197 | EmailSpec::EmailViewer::save_and_open_all_text_emails 198 | end 199 | 200 | Then /^save and open all html emails$/ do 201 | EmailSpec::EmailViewer::save_and_open_all_html_emails 202 | end 203 | 204 | Then /^save and open all raw emails$/ do 205 | EmailSpec::EmailViewer::save_and_open_all_raw_emails 206 | end 207 | -------------------------------------------------------------------------------- /features/step_definitions/user_steps.rb: -------------------------------------------------------------------------------- 1 | ### UTILITY METHODS ### 2 | 3 | def create_visitor 4 | @visitor ||= { :name => "Testy McUserton", :email => "example@example.com", 5 | :password => "changeme", :password_confirmation => "changeme" } 6 | end 7 | 8 | def find_user 9 | @user ||= User.first conditions: {:email => @visitor[:email]} 10 | end 11 | 12 | def create_unconfirmed_user 13 | create_visitor 14 | delete_user 15 | sign_up 16 | visit '/users/sign_out' 17 | end 18 | 19 | def create_user 20 | create_visitor 21 | delete_user 22 | @user = FactoryGirl.create(:user, email: @visitor[:email]) 23 | end 24 | 25 | def delete_user 26 | @user ||= User.first conditions: {:email => @visitor[:email]} 27 | @user.destroy unless @user.nil? 28 | end 29 | 30 | def sign_up 31 | delete_user 32 | visit '/users/sign_up' 33 | fill_in "Name", :with => @visitor[:name] 34 | fill_in "Email", :with => @visitor[:email] 35 | fill_in "user_password", :with => @visitor[:password] 36 | fill_in "user_password_confirmation", :with => @visitor[:password_confirmation] 37 | click_button "Sign up" 38 | find_user 39 | end 40 | 41 | def sign_in 42 | visit '/users/sign_in' 43 | fill_in "Email", :with => @visitor[:email] 44 | fill_in "Password", :with => @visitor[:password] 45 | click_button "Sign in" 46 | end 47 | 48 | ### GIVEN ### 49 | Given /^I am not logged in$/ do 50 | visit '/users/sign_out' 51 | end 52 | 53 | Given /^I am logged in$/ do 54 | create_user 55 | sign_in 56 | end 57 | 58 | Given /^I exist as a user$/ do 59 | create_user 60 | end 61 | 62 | Given /^I do not exist as a user$/ do 63 | create_visitor 64 | delete_user 65 | end 66 | 67 | Given /^I exist as an unconfirmed user$/ do 68 | create_unconfirmed_user 69 | end 70 | 71 | ### WHEN ### 72 | When /^I sign in with valid credentials$/ do 73 | create_visitor 74 | sign_in 75 | end 76 | 77 | When /^I sign out$/ do 78 | visit '/users/sign_out' 79 | end 80 | 81 | When /^I sign up with valid user data$/ do 82 | create_visitor 83 | sign_up 84 | end 85 | 86 | When /^I sign up with an invalid email$/ do 87 | create_visitor 88 | @visitor = @visitor.merge(:email => "notanemail") 89 | sign_up 90 | end 91 | 92 | When /^I sign up without a password confirmation$/ do 93 | create_visitor 94 | @visitor = @visitor.merge(:password_confirmation => "") 95 | sign_up 96 | end 97 | 98 | When /^I sign up without a password$/ do 99 | create_visitor 100 | @visitor = @visitor.merge(:password => "") 101 | sign_up 102 | end 103 | 104 | When /^I sign up with a mismatched password confirmation$/ do 105 | create_visitor 106 | @visitor = @visitor.merge(:password_confirmation => "changeme123") 107 | sign_up 108 | end 109 | 110 | When /^I return to the site$/ do 111 | visit '/' 112 | end 113 | 114 | When /^I sign in with a wrong email$/ do 115 | @visitor = @visitor.merge(:email => "wrong@example.com") 116 | sign_in 117 | end 118 | 119 | When /^I sign in with a wrong password$/ do 120 | @visitor = @visitor.merge(:password => "wrongpass") 121 | sign_in 122 | end 123 | 124 | When /^I edit my account details$/ do 125 | click_link "Edit account" 126 | fill_in "Name", :with => "newname" 127 | fill_in "user_current_password", :with => @visitor[:password] 128 | click_button "Update" 129 | end 130 | 131 | When /^I look at the list of users$/ do 132 | visit '/' 133 | end 134 | 135 | ### THEN ### 136 | Then /^I should be signed in$/ do 137 | page.should have_content "Logout" 138 | page.should_not have_content "Sign up" 139 | page.should_not have_content "Login" 140 | end 141 | 142 | Then /^I should be signed out$/ do 143 | page.should have_content "Sign up" 144 | page.should have_content "Login" 145 | page.should_not have_content "Logout" 146 | end 147 | 148 | Then /^I see an unconfirmed account message$/ do 149 | page.should have_content "You have to confirm your account before continuing." 150 | end 151 | 152 | Then /^I see a successful sign in message$/ do 153 | page.should have_content "Signed in successfully." 154 | end 155 | 156 | Then /^I should see a successful sign up message$/ do 157 | page.should have_content "Welcome! You have signed up successfully." 158 | end 159 | 160 | Then /^I should see an invalid email message$/ do 161 | page.should have_content "Emailis invalid" 162 | end 163 | 164 | Then /^I should see a missing password message$/ do 165 | page.should have_content "Passwordcan't be blank" 166 | end 167 | 168 | Then /^I should see a missing password confirmation message$/ do 169 | page.should have_content "Passworddoesn't match confirmation" 170 | end 171 | 172 | Then /^I should see a mismatched password message$/ do 173 | page.should have_content "Passworddoesn't match confirmation" 174 | end 175 | 176 | Then /^I should see a signed out message$/ do 177 | page.should have_content "Signed out successfully." 178 | end 179 | 180 | Then /^I see an invalid login message$/ do 181 | page.should have_content "Invalid email or password." 182 | end 183 | 184 | Then /^I should see an account edited message$/ do 185 | page.should have_content "You updated your account successfully." 186 | end 187 | 188 | Then /^I should see my name$/ do 189 | create_user 190 | page.should have_content @user[:name] 191 | end 192 | -------------------------------------------------------------------------------- /features/support/email_spec.rb: -------------------------------------------------------------------------------- 1 | require 'email_spec/cucumber' 2 | -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. 2 | # It is recommended to regenerate this file in the future when you upgrade to a 3 | # newer version of cucumber-rails. Consider adding your own code to a new file 4 | # instead of editing this one. Cucumber will automatically load all features/**/*.rb 5 | # files. 6 | 7 | require 'cucumber/rails' 8 | 9 | # Capybara defaults to CSS3 selectors rather than XPath. 10 | # If you'd prefer to use XPath, just uncomment this line and adjust any 11 | # selectors in your step definitions to use the XPath syntax. 12 | # Capybara.default_selector = :xpath 13 | 14 | # By default, any exception happening in your Rails application will bubble up 15 | # to Cucumber so that your scenario will fail. This is a different from how 16 | # your application behaves in the production environment, where an error page will 17 | # be rendered instead. 18 | # 19 | # Sometimes we want to override this default behaviour and allow Rails to rescue 20 | # exceptions and display an error page (just like when the app is running in production). 21 | # Typical scenarios where you want to do this is when you test your error pages. 22 | # There are two ways to allow Rails to rescue exceptions: 23 | # 24 | # 1) Tag your scenario (or feature) with @allow-rescue 25 | # 26 | # 2) Set the value below to true. Beware that doing this globally is not 27 | # recommended as it will mask a lot of errors for you! 28 | # 29 | ActionController::Base.allow_rescue = false 30 | 31 | # Remove/comment out the lines below if your app doesn't have a database. 32 | # For some databases (like MongoDB and CouchDB) you may need to use :truncation instead. 33 | begin 34 | DatabaseCleaner.strategy = :transaction 35 | rescue NameError 36 | raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." 37 | end 38 | 39 | # You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios. 40 | # See the DatabaseCleaner documentation for details. Example: 41 | # 42 | # Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do 43 | # # { :except => [:widgets] } may not do what you expect here 44 | # # as Cucumber::Rails::Database.javascript_strategy overrides 45 | # # this setting. 46 | # DatabaseCleaner.strategy = :truncation 47 | # end 48 | # 49 | # Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do 50 | # DatabaseCleaner.strategy = :transaction 51 | # end 52 | # 53 | 54 | # Possible values are :truncation and :transaction 55 | # The :transaction strategy is faster, but might give you threading problems. 56 | # See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature 57 | Cucumber::Rails::Database.javascript_strategy = :truncation 58 | 59 | -------------------------------------------------------------------------------- /features/support/paths.rb: -------------------------------------------------------------------------------- 1 | module NavigationHelpers 2 | # Maps a name to a path. Used by the 3 | # 4 | # When /^I go to (.+)$/ do |page_name| 5 | # 6 | # step definition in web_steps.rb 7 | # 8 | def path_to(page_name) 9 | case page_name 10 | 11 | when /the home\s?page/ 12 | '/' 13 | 14 | when /the sign up page/ 15 | '/users/sign_up' 16 | 17 | when /the sign in page/ 18 | '/users/sign_in' 19 | 20 | # Add more mappings here. 21 | # Here is an example that pulls values out of the Regexp: 22 | # 23 | # when /^(.*)'s profile page$/i 24 | # user_profile_path(User.find_by_login($1)) 25 | 26 | else 27 | begin 28 | page_name =~ /the (.*) page/ 29 | path_components = $1.split(/\s+/) 30 | self.send(path_components.push('path').join('_').to_sym) 31 | rescue Object => e 32 | raise "Can't find mapping from \"#{page_name}\" to a path.\n" + 33 | "Now, go and add a mapping in #{__FILE__}" 34 | end 35 | end 36 | end 37 | end 38 | 39 | World(NavigationHelpers) 40 | -------------------------------------------------------------------------------- /features/users/sign_in.feature: -------------------------------------------------------------------------------- 1 | Feature: Sign in 2 | In order to get access to protected sections of the site 3 | A user 4 | Should be able to sign in 5 | 6 | Scenario: User is not signed up 7 | Given I do not exist as a user 8 | When I sign in with valid credentials 9 | Then I see an invalid login message 10 | And I should be signed out 11 | 12 | Scenario: User signs in successfully 13 | Given I exist as a user 14 | And I am not logged in 15 | When I sign in with valid credentials 16 | Then I see a successful sign in message 17 | When I return to the site 18 | Then I should be signed in 19 | 20 | Scenario: User enters wrong email 21 | Given I exist as a user 22 | And I am not logged in 23 | When I sign in with a wrong email 24 | Then I see an invalid login message 25 | And I should be signed out 26 | 27 | Scenario: User enters wrong password 28 | Given I exist as a user 29 | And I am not logged in 30 | When I sign in with a wrong password 31 | Then I see an invalid login message 32 | And I should be signed out 33 | 34 | -------------------------------------------------------------------------------- /features/users/sign_out.feature: -------------------------------------------------------------------------------- 1 | Feature: Sign out 2 | To protect my account from unauthorized access 3 | A signed in user 4 | Should be able to sign out 5 | 6 | Scenario: User signs out 7 | Given I am logged in 8 | When I sign out 9 | Then I should see a signed out message 10 | When I return to the site 11 | Then I should be signed out 12 | -------------------------------------------------------------------------------- /features/users/sign_up.feature: -------------------------------------------------------------------------------- 1 | Feature: Sign up 2 | In order to get access to protected sections of the site 3 | As a user 4 | I want to be able to sign up 5 | 6 | Background: 7 | Given I am not logged in 8 | 9 | Scenario: User signs up with valid data 10 | When I sign up with valid user data 11 | Then I should see a successful sign up message 12 | 13 | Scenario: User signs up with invalid email 14 | When I sign up with an invalid email 15 | Then I should see an invalid email message 16 | 17 | Scenario: User signs up without password 18 | When I sign up without a password 19 | Then I should see a missing password message 20 | 21 | Scenario: User signs up without password confirmation 22 | When I sign up without a password confirmation 23 | Then I should see a missing password confirmation message 24 | 25 | Scenario: User signs up with mismatched password and confirmation 26 | When I sign up with a mismatched password confirmation 27 | Then I should see a mismatched password message 28 | -------------------------------------------------------------------------------- /features/users/user_edit.feature: -------------------------------------------------------------------------------- 1 | Feature: Edit User 2 | As a registered user of the website 3 | I want to edit my user profile 4 | so I can change my username 5 | 6 | Scenario: I sign in and edit my account 7 | Given I am logged in 8 | When I edit my account details 9 | Then I should see an account edited message 10 | -------------------------------------------------------------------------------- /features/users/user_show.feature: -------------------------------------------------------------------------------- 1 | Feature: Show Users 2 | As a visitor to the website 3 | I want to see registered users listed on the homepage 4 | so I can know if the site has users 5 | 6 | Scenario: Viewing users 7 | Given I exist as a user 8 | When I look at the list of users 9 | Then I should see my name 10 | -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RailsApps/rails3-bootstrap-devise-cancan/5de4abf3fda44843e82e1c372ed22a0e30069ad3/lib/assets/.gitkeep -------------------------------------------------------------------------------- /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RailsApps/rails3-bootstrap-devise-cancan/5de4abf3fda44843e82e1c372ed22a0e30069ad3/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /lib/tasks/cucumber.rake: -------------------------------------------------------------------------------- 1 | # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. 2 | # It is recommended to regenerate this file in the future when you upgrade to a 3 | # newer version of cucumber-rails. Consider adding your own code to a new file 4 | # instead of editing this one. Cucumber will automatically load all features/**/*.rb 5 | # files. 6 | 7 | 8 | unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks 9 | 10 | vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first 11 | $LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil? 12 | 13 | begin 14 | require 'cucumber/rake/task' 15 | 16 | namespace :cucumber do 17 | Cucumber::Rake::Task.new({:ok => 'test:prepare'}, 'Run features that should pass') do |t| 18 | t.binary = vendored_cucumber_bin # If nil, the gem's binary is used. 19 | t.fork = true # You may get faster startup if you set this to false 20 | t.profile = 'default' 21 | end 22 | 23 | Cucumber::Rake::Task.new({:wip => 'test:prepare'}, 'Run features that are being worked on') do |t| 24 | t.binary = vendored_cucumber_bin 25 | t.fork = true # You may get faster startup if you set this to false 26 | t.profile = 'wip' 27 | end 28 | 29 | Cucumber::Rake::Task.new({:rerun => 'test:prepare'}, 'Record failing features and run only them if any exist') do |t| 30 | t.binary = vendored_cucumber_bin 31 | t.fork = true # You may get faster startup if you set this to false 32 | t.profile = 'rerun' 33 | end 34 | 35 | desc 'Run all features' 36 | task :all => [:ok, :wip] 37 | 38 | task :statsetup do 39 | require 'rails/code_statistics' 40 | ::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features') 41 | ::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features') 42 | end 43 | end 44 | desc 'Alias for cucumber:ok' 45 | task :cucumber => 'cucumber:ok' 46 | 47 | task :default => :cucumber 48 | 49 | task :features => :cucumber do 50 | STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***" 51 | end 52 | 53 | # In case we don't have the generic Rails test:prepare hook, append a no-op task that we can depend upon. 54 | task 'test:prepare' do 55 | end 56 | 57 | task :stats => 'cucumber:statsetup' 58 | rescue LoadError 59 | desc 'cucumber rake task not available (cucumber not installed)' 60 | task :cucumber do 61 | abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin' 62 | end 63 | end 64 | 65 | end 66 | -------------------------------------------------------------------------------- /lib/templates/erb/scaffold/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%%= simple_form_for(@<%= singular_table_name %>) do |f| %> 2 | <%%= f.error_notification %> 3 | 4 |You may have mistyped the address or the page may have moved.
24 |Maybe you tried to change something you didn't have access to.
24 |