├── .gitignore
├── .rspec
├── Gemfile
├── Gemfile.lock
├── README.rdoc
├── Rakefile
├── app
├── assets
│ ├── images
│ │ └── .keep
│ ├── javascripts
│ │ ├── application.js
│ │ ├── sample.coffee
│ │ ├── user_sessions.coffee
│ │ └── users.coffee
│ └── stylesheets
│ │ ├── application.css
│ │ ├── sample.scss
│ │ ├── scaffolds.scss
│ │ ├── user_sessions.scss
│ │ └── users.scss
├── controllers
│ ├── api
│ │ └── v1
│ │ │ ├── application_base_controller.rb
│ │ │ ├── password_resets_controller.rb
│ │ │ ├── sample_controller.rb
│ │ │ ├── user_sessions_controller.rb
│ │ │ └── users_controller.rb
│ ├── application_controller.rb
│ └── concerns
│ │ └── .keep
├── helpers
│ ├── api
│ │ └── v1
│ │ │ └── password_resets_helper.rb
│ ├── application_helper.rb
│ ├── sample_helper.rb
│ ├── user_sessions_helper.rb
│ └── users_helper.rb
├── mailers
│ ├── .keep
│ ├── application_mailer.rb
│ └── user_mailer.rb
├── models
│ ├── .keep
│ ├── api_key.rb
│ ├── concerns
│ │ └── .keep
│ ├── department.rb
│ ├── user.rb
│ └── user_department.rb
└── views
│ ├── api
│ └── v1
│ │ ├── password_resets
│ │ ├── create.html.erb
│ │ ├── edit.html.erb
│ │ └── update.html.erb
│ │ ├── sample
│ │ ├── admin.json.jbuilder
│ │ ├── public.json.jbuilder
│ │ └── restrict.json.jbuilder
│ │ ├── user_sessions
│ │ ├── create.html.erb
│ │ ├── create.json.jbuilder
│ │ ├── destroy.html.erb
│ │ └── new.html.erb
│ │ └── users
│ │ ├── index.json.jbuilder
│ │ └── show.json.jbuilder
│ ├── layouts
│ ├── application.html.erb
│ ├── mailer.html.erb
│ └── mailer.text.erb
│ └── user_mailer
│ └── reset_password_email.text.erb
├── bin
├── bundle
├── rails
├── rake
├── setup
└── spring
├── config.ru
├── config
├── application.rb
├── boot.rb
├── database.yml
├── environment.rb
├── environments
│ ├── development.rb
│ ├── production.rb
│ └── test.rb
├── initializers
│ ├── assets.rb
│ ├── backtrace_silencers.rb
│ ├── cookies_serializer.rb
│ ├── filter_parameter_logging.rb
│ ├── inflections.rb
│ ├── mime_types.rb
│ ├── session_store.rb
│ ├── sorcery.rb
│ └── wrap_parameters.rb
├── locales
│ └── en.yml
├── routes.rb
└── secrets.yml
├── db
├── migrate
│ ├── 20150520221548_sorcery_core.rb
│ ├── 20150526221756_create_api_keys.rb
│ ├── 20150529142034_add_active_api_key.rb
│ ├── 20150607122809_create_user_departments.rb
│ ├── 20150607134905_create_departments.rb
│ └── 20150922120215_sorcery_reset_password.rb
├── schema.rb
└── seeds.rb
├── lib
├── assets
│ └── .keep
└── tasks
│ └── .keep
├── log
└── .keep
├── public
├── 404.html
├── 422.html
├── 500.html
├── favicon.ico
└── robots.txt
└── spec
├── controllers
├── password_resets_controller_spec.rb
├── sample_controller_spec.rb
├── user_sessions_controller_spec.rb
└── users_controller_spec.rb
├── factories
├── api_keys.rb
├── department.rb
├── user_departments.rb
└── users.rb
├── helpers
├── api
│ └── v1
│ │ └── password_resets_helper_spec.rb
├── sample_helper_spec.rb
├── user_sessions_helper_spec.rb
└── users_helper_spec.rb
├── mailers
└── user_mailer_spec.rb
├── models
├── api_key_spec.rb
├── department_spec.rb
├── user_department_spec.rb
└── user_spec.rb
├── rails_helper.rb
├── requests
└── users_spec.rb
├── routing
└── users_routing_spec.rb
├── spec_helper.rb
└── views
├── sample
├── public.html.erb_spec.rb
└── restrict.html.erb_spec.rb
├── user_sessions
├── create.html.erb_spec.rb
├── destroy.html.erb_spec.rb
└── new.html.erb_spec.rb
└── users
├── edit.html.erb_spec.rb
├── index.html.erb_spec.rb
├── new.html.erb_spec.rb
└── show.html.erb_spec.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile '~/.gitignore_global'
6 |
7 | # Ignore bundler config.
8 | /.bundle
9 |
10 | # Ignore the default SQLite database.
11 | /db/*.sqlite3
12 | /db/*.sqlite3-journal
13 |
14 | # Ignore all logfiles and tempfiles.
15 | /log/*
16 | !/log/.keep
17 | /tmp
18 | /.idea
19 | /vendor
20 |
21 | /config/settings.yml
22 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 | --require spec_helper
3 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 |
4 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
5 | gem 'rails', '4.2.1'
6 | # Use sqlite3 as the database for Active Record
7 | gem 'sqlite3'
8 | # Use SCSS for stylesheets
9 | gem 'sass-rails', '~> 5.0'
10 | # Use Uglifier as compressor for JavaScript assets
11 | gem 'uglifier', '>= 1.3.0'
12 | # Use CoffeeScript for .coffee assets and views
13 | gem 'coffee-rails', '~> 4.1.0'
14 | # See https://github.com/rails/execjs#readme for more supported runtimes
15 | # gem 'therubyracer', platforms: :ruby
16 |
17 | # Use jquery as the JavaScript library
18 | gem 'jquery-rails'
19 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
20 | gem 'turbolinks'
21 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
22 | gem 'jbuilder', '~> 2.0'
23 | # bundle exec rake doc:rails generates the API under doc/api.
24 | gem 'sdoc', '~> 0.4.0', group: :doc
25 |
26 | # Use ActiveModel has_secure_password
27 | # gem 'bcrypt', '~> 3.1.7'
28 |
29 | # Use Unicorn as the app server
30 | # gem 'unicorn'
31 |
32 | # Use Capistrano for deployment
33 | # gem 'capistrano-rails', group: :development
34 |
35 | gem 'sorcery'
36 | gem 'rspec-rails'
37 |
38 | group :development, :test do
39 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console
40 | gem 'pry-byebug'
41 |
42 | # Access an IRB console on exception pages or by using <%= console %> in views
43 | gem 'web-console', '~> 2.0'
44 |
45 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
46 | gem 'spring'
47 | gem 'spring-commands-rspec'
48 | end
49 |
50 | group :test do
51 | gem 'factory_girl_rails'
52 | end
53 |
54 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | actionmailer (4.2.1)
5 | actionpack (= 4.2.1)
6 | actionview (= 4.2.1)
7 | activejob (= 4.2.1)
8 | mail (~> 2.5, >= 2.5.4)
9 | rails-dom-testing (~> 1.0, >= 1.0.5)
10 | actionpack (4.2.1)
11 | actionview (= 4.2.1)
12 | activesupport (= 4.2.1)
13 | rack (~> 1.6)
14 | rack-test (~> 0.6.2)
15 | rails-dom-testing (~> 1.0, >= 1.0.5)
16 | rails-html-sanitizer (~> 1.0, >= 1.0.1)
17 | actionview (4.2.1)
18 | activesupport (= 4.2.1)
19 | builder (~> 3.1)
20 | erubis (~> 2.7.0)
21 | rails-dom-testing (~> 1.0, >= 1.0.5)
22 | rails-html-sanitizer (~> 1.0, >= 1.0.1)
23 | activejob (4.2.1)
24 | activesupport (= 4.2.1)
25 | globalid (>= 0.3.0)
26 | activemodel (4.2.1)
27 | activesupport (= 4.2.1)
28 | builder (~> 3.1)
29 | activerecord (4.2.1)
30 | activemodel (= 4.2.1)
31 | activesupport (= 4.2.1)
32 | arel (~> 6.0)
33 | activesupport (4.2.1)
34 | i18n (~> 0.7)
35 | json (~> 1.7, >= 1.7.7)
36 | minitest (~> 5.1)
37 | thread_safe (~> 0.3, >= 0.3.4)
38 | tzinfo (~> 1.1)
39 | arel (6.0.0)
40 | bcrypt (3.1.10)
41 | binding_of_caller (0.7.2)
42 | debug_inspector (>= 0.0.1)
43 | builder (3.2.2)
44 | byebug (4.0.5)
45 | columnize (= 0.9.0)
46 | coderay (1.1.0)
47 | coffee-rails (4.1.0)
48 | coffee-script (>= 2.2.0)
49 | railties (>= 4.0.0, < 5.0)
50 | coffee-script (2.4.1)
51 | coffee-script-source
52 | execjs
53 | coffee-script-source (1.9.1.1)
54 | columnize (0.9.0)
55 | debug_inspector (0.0.2)
56 | diff-lcs (1.2.5)
57 | erubis (2.7.0)
58 | execjs (2.5.2)
59 | factory_girl (4.5.0)
60 | activesupport (>= 3.0.0)
61 | factory_girl_rails (4.5.0)
62 | factory_girl (~> 4.5.0)
63 | railties (>= 3.0.0)
64 | faraday (0.9.1)
65 | multipart-post (>= 1.2, < 3)
66 | globalid (0.3.5)
67 | activesupport (>= 4.1.0)
68 | i18n (0.7.0)
69 | jbuilder (2.2.16)
70 | activesupport (>= 3.0.0, < 5)
71 | multi_json (~> 1.2)
72 | jquery-rails (4.0.3)
73 | rails-dom-testing (~> 1.0)
74 | railties (>= 4.2.0)
75 | thor (>= 0.14, < 2.0)
76 | json (1.8.2)
77 | jwt (1.5.0)
78 | loofah (2.0.2)
79 | nokogiri (>= 1.5.9)
80 | mail (2.6.3)
81 | mime-types (>= 1.16, < 3)
82 | method_source (0.8.2)
83 | mime-types (2.5)
84 | mini_portile (0.6.2)
85 | minitest (5.6.1)
86 | multi_json (1.11.0)
87 | multi_xml (0.5.5)
88 | multipart-post (2.0.0)
89 | nokogiri (1.6.6.2)
90 | mini_portile (~> 0.6.0)
91 | oauth (0.4.7)
92 | oauth2 (1.0.0)
93 | faraday (>= 0.8, < 0.10)
94 | jwt (~> 1.0)
95 | multi_json (~> 1.3)
96 | multi_xml (~> 0.5)
97 | rack (~> 1.2)
98 | pry (0.10.1)
99 | coderay (~> 1.1.0)
100 | method_source (~> 0.8.1)
101 | slop (~> 3.4)
102 | pry-byebug (3.1.0)
103 | byebug (~> 4.0)
104 | pry (~> 0.10)
105 | rack (1.6.1)
106 | rack-test (0.6.3)
107 | rack (>= 1.0)
108 | rails (4.2.1)
109 | actionmailer (= 4.2.1)
110 | actionpack (= 4.2.1)
111 | actionview (= 4.2.1)
112 | activejob (= 4.2.1)
113 | activemodel (= 4.2.1)
114 | activerecord (= 4.2.1)
115 | activesupport (= 4.2.1)
116 | bundler (>= 1.3.0, < 2.0)
117 | railties (= 4.2.1)
118 | sprockets-rails
119 | rails-deprecated_sanitizer (1.0.3)
120 | activesupport (>= 4.2.0.alpha)
121 | rails-dom-testing (1.0.6)
122 | activesupport (>= 4.2.0.beta, < 5.0)
123 | nokogiri (~> 1.6.0)
124 | rails-deprecated_sanitizer (>= 1.0.1)
125 | rails-html-sanitizer (1.0.2)
126 | loofah (~> 2.0)
127 | railties (4.2.1)
128 | actionpack (= 4.2.1)
129 | activesupport (= 4.2.1)
130 | rake (>= 0.8.7)
131 | thor (>= 0.18.1, < 2.0)
132 | rake (10.4.2)
133 | rdoc (4.2.0)
134 | json (~> 1.4)
135 | rspec-core (3.2.3)
136 | rspec-support (~> 3.2.0)
137 | rspec-expectations (3.2.1)
138 | diff-lcs (>= 1.2.0, < 2.0)
139 | rspec-support (~> 3.2.0)
140 | rspec-mocks (3.2.1)
141 | diff-lcs (>= 1.2.0, < 2.0)
142 | rspec-support (~> 3.2.0)
143 | rspec-rails (3.2.1)
144 | actionpack (>= 3.0, < 4.3)
145 | activesupport (>= 3.0, < 4.3)
146 | railties (>= 3.0, < 4.3)
147 | rspec-core (~> 3.2.0)
148 | rspec-expectations (~> 3.2.0)
149 | rspec-mocks (~> 3.2.0)
150 | rspec-support (~> 3.2.0)
151 | rspec-support (3.2.2)
152 | sass (3.4.13)
153 | sass-rails (5.0.3)
154 | railties (>= 4.0.0, < 5.0)
155 | sass (~> 3.1)
156 | sprockets (>= 2.8, < 4.0)
157 | sprockets-rails (>= 2.0, < 4.0)
158 | tilt (~> 1.1)
159 | sdoc (0.4.1)
160 | json (~> 1.7, >= 1.7.7)
161 | rdoc (~> 4.0)
162 | slop (3.6.0)
163 | sorcery (0.9.1)
164 | bcrypt (~> 3.1)
165 | oauth (~> 0.4, >= 0.4.4)
166 | oauth2 (>= 0.8.0)
167 | spring (1.3.6)
168 | spring-commands-rspec (1.0.4)
169 | spring (>= 0.9.1)
170 | sprockets (3.1.0)
171 | rack (~> 1.0)
172 | sprockets-rails (2.3.1)
173 | actionpack (>= 3.0)
174 | activesupport (>= 3.0)
175 | sprockets (>= 2.8, < 4.0)
176 | sqlite3 (1.3.10)
177 | thor (0.19.1)
178 | thread_safe (0.3.5)
179 | tilt (1.4.1)
180 | turbolinks (2.5.3)
181 | coffee-rails
182 | tzinfo (1.2.2)
183 | thread_safe (~> 0.1)
184 | uglifier (2.7.1)
185 | execjs (>= 0.3.0)
186 | json (>= 1.8.0)
187 | web-console (2.1.2)
188 | activemodel (>= 4.0)
189 | binding_of_caller (>= 0.7.2)
190 | railties (>= 4.0)
191 | sprockets-rails (>= 2.0, < 4.0)
192 |
193 | PLATFORMS
194 | ruby
195 |
196 | DEPENDENCIES
197 | coffee-rails (~> 4.1.0)
198 | factory_girl_rails
199 | jbuilder (~> 2.0)
200 | jquery-rails
201 | pry-byebug
202 | rails (= 4.2.1)
203 | rspec-rails
204 | sass-rails (~> 5.0)
205 | sdoc (~> 0.4.0)
206 | sorcery
207 | spring
208 | spring-commands-rspec
209 | sqlite3
210 | turbolinks
211 | uglifier (>= 1.3.0)
212 | web-console (~> 2.0)
213 |
--------------------------------------------------------------------------------
/README.rdoc:
--------------------------------------------------------------------------------
1 | == About
2 |
3 | This is a Sample Authentication API Appliction with Ruby on Rails, sorcery.
4 |
5 | == Environments
6 |
7 | * Ruby 2.1.2
8 |
9 | * Rails 4.2.1
10 |
11 | * sorcery 0.9.1
12 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require File.expand_path('../config/application', __FILE__)
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/app/assets/images/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/app/assets/images/.keep
--------------------------------------------------------------------------------
/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 any plugin's vendor/assets/javascripts directory 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 | // compiled file.
9 | //
10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11 | // about supported directives.
12 | //
13 | //= require jquery
14 | //= require jquery_ujs
15 | //= require turbolinks
16 | //= require_tree .
17 |
--------------------------------------------------------------------------------
/app/assets/javascripts/sample.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://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/user_sessions.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://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/users.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://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
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 any plugin's vendor/assets/stylesheets directory 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 bottom of the
9 | * compiled file so the styles you add here take precedence over styles defined in any styles
10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11 | * file per style scope.
12 | *
13 | *= require_tree .
14 | *= require_self
15 | */
16 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/sample.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the sample controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/scaffolds.scss:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #fff;
3 | color: #333;
4 | font-family: verdana, arial, helvetica, sans-serif;
5 | font-size: 13px;
6 | line-height: 18px;
7 | }
8 |
9 | p, ol, ul, td {
10 | font-family: verdana, arial, helvetica, sans-serif;
11 | font-size: 13px;
12 | line-height: 18px;
13 | }
14 |
15 | pre {
16 | background-color: #eee;
17 | padding: 10px;
18 | font-size: 11px;
19 | }
20 |
21 | a {
22 | color: #000;
23 | &:visited {
24 | color: #666;
25 | }
26 | &:hover {
27 | color: #fff;
28 | background-color: #000;
29 | }
30 | }
31 |
32 | div {
33 | &.field, &.actions {
34 | margin-bottom: 10px;
35 | }
36 | }
37 |
38 | #notice {
39 | color: green;
40 | }
41 |
42 | .field_with_errors {
43 | padding: 2px;
44 | background-color: red;
45 | display: table;
46 | }
47 |
48 | #error_explanation {
49 | width: 450px;
50 | border: 2px solid red;
51 | padding: 7px;
52 | padding-bottom: 0;
53 | margin-bottom: 20px;
54 | background-color: #f0f0f0;
55 | h2 {
56 | text-align: left;
57 | font-weight: bold;
58 | padding: 5px 5px 5px 15px;
59 | font-size: 12px;
60 | margin: -7px;
61 | margin-bottom: 0px;
62 | background-color: #c00;
63 | color: #fff;
64 | }
65 | ul li {
66 | font-size: 12px;
67 | list-style: square;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/user_sessions.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the UserSessions controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/users.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the users 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/api/v1/application_base_controller.rb:
--------------------------------------------------------------------------------
1 | module Api
2 | module V1
3 | class ApplicationBaseController < ApplicationController
4 | before_action :require_valid_token
5 |
6 | private
7 |
8 | def require_valid_token
9 | access_token = request.headers[:HTTP_ACCESS_TOKEN]
10 | if !User.login?(access_token)
11 | respond_to do |format|
12 | format.json { render nothing: true, status: :unauthorized }
13 | end
14 | end
15 | end
16 |
17 | def administrator_only
18 | access_token = request.headers[:HTTP_ACCESS_TOKEN]
19 | api_key = ApiKey.find_by_access_token(access_token)
20 | user = User.find(api_key.user_id)
21 | if user.user_department.department_id != Department::ADMINISTRATOR
22 | respond_to do |format|
23 | format.json { render nothing: true, status: :unauthorized }
24 | end
25 | end
26 | end
27 | end
28 | end
29 | end
--------------------------------------------------------------------------------
/app/controllers/api/v1/password_resets_controller.rb:
--------------------------------------------------------------------------------
1 | class Api::V1::PasswordResetsController < Api::V1::ApplicationBaseController
2 | skip_before_filter :require_valid_token
3 |
4 | def create
5 | @user = User.find_by_email(params[:email])
6 |
7 | if @user
8 | respond_to do |format|
9 | @user.deliver_reset_password_instructions!
10 | format.json { render nothing: true, status: :created }
11 | end
12 | else
13 | respond_to do |format|
14 | format.json { render nothing: true, status: :not_found }
15 | end
16 | end
17 | end
18 |
19 | def edit
20 | if set_token_user_from_params?
21 | respond_to do |format|
22 | format.json { render nothing: true, status: :ok }
23 | end
24 | else
25 | respond_to do |format|
26 | format.json { render nothing: true, status: :not_found }
27 | end
28 | end
29 | end
30 |
31 | def update
32 | if set_token_user_from_params?
33 | @user.password_confirmation = params[:user][:password_confirmation]
34 |
35 | if @user.change_password!(params[:user][:password])
36 | respond_to do |format|
37 | format.json { render nothing: true, status: :ok }
38 | end
39 | else
40 | respond_to do |format|
41 | format.json { render nothing: true, status: :not_acceptable }
42 | end
43 | end
44 | else
45 | respond_to do |format|
46 | format.json { render nothing: true, status: :not_found }
47 | end
48 | end
49 | end
50 |
51 | private
52 | def set_token_user_from_params?
53 | @token = params[:id]
54 | @user = User.load_from_reset_password_token(params[:id])
55 | return !@user.blank?
56 | end
57 | end
58 |
--------------------------------------------------------------------------------
/app/controllers/api/v1/sample_controller.rb:
--------------------------------------------------------------------------------
1 | module Api
2 | module V1
3 | class SampleController < Api::V1::ApplicationBaseController
4 | skip_before_filter :require_valid_token, only: :public
5 | before_filter :administrator_only, only: :admin
6 |
7 | def public
8 | @message = 'public'
9 | end
10 |
11 | def restrict
12 | @message = 'authorized'
13 | end
14 |
15 | def admin
16 | @message = 'admin'
17 | end
18 | end
19 | end
20 | end
--------------------------------------------------------------------------------
/app/controllers/api/v1/user_sessions_controller.rb:
--------------------------------------------------------------------------------
1 | module Api
2 | module V1
3 | class UserSessionsController < Api::V1::ApplicationBaseController
4 | skip_before_filter :require_valid_token, only: :create
5 |
6 | def create
7 | if @user = login(login_user[:email], login_user[:password])
8 | api_key = @user.activate
9 | @access_token = api_key.access_token
10 | else
11 | respond_to do |format|
12 | format.json { render nothing: true, status: :not_found }
13 | end
14 | end
15 | end
16 |
17 | def destroy
18 | access_token = request.headers[:HTTP_ACCESS_TOKEN]
19 | api_key = ApiKey.find_by_access_token(access_token)
20 | if api_key
21 | user = User.find(api_key.user_id)
22 | user.inactivate
23 | respond_to do |format|
24 | format.json { render nothing: true, status: :ok }
25 | end
26 | end
27 | end
28 |
29 | private
30 |
31 | def login_user
32 | params[:user]
33 | end
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/app/controllers/api/v1/users_controller.rb:
--------------------------------------------------------------------------------
1 | module Api
2 | module V1
3 | class UsersController < Api::V1::ApplicationBaseController
4 | before_action :set_user, only: [:show, :edit, :update, :destroy]
5 | skip_before_filter :require_valid_token, only: :create
6 |
7 | # GET /users.json
8 | def index
9 | @users = User.all
10 | end
11 |
12 | # GET /users/1.json
13 | def show
14 | if !@user
15 | respond_to do |format|
16 | format.json { render nothing: true, status: :not_found }
17 | end
18 | end
19 | end
20 |
21 | # POST /users.json
22 | def create
23 | respond_to do |format|
24 | @user = User.new(user_params)
25 |
26 | if @user.save_relation(department_params)
27 | format.json { render nothing: true, status: :created }
28 | else
29 | format.json { render nothing: true, status: :bad_request }
30 | end
31 | end
32 | end
33 |
34 | # PATCH/PUT /users/1.json
35 | def update
36 | respond_to do |format|
37 | if @user.update_relation(user_params, department_params)
38 | format.json { render :show }
39 | else
40 | format.json { render json: @user.errors, status: :unprocessable_entity }
41 | end
42 | end
43 | end
44 |
45 | # DELETE /users/1.json
46 | def destroy
47 | @user.destroy
48 | respond_to do |format|
49 | format.json { head :no_content }
50 | end
51 | end
52 |
53 | private
54 | # Use callbacks to share common setup or constraints between actions.
55 | def set_user
56 | @user = User.find_by_id(params[:id])
57 | end
58 |
59 | # Never trust parameters from the scary internet, only allow the white list through.
60 | def user_params
61 | params.require(:user).permit(:email, :name, :password, :password_confirmation)
62 | end
63 |
64 | def department_params
65 | params.require(:department).permit(:department_id)
66 | end
67 | end
68 | end
69 | end
--------------------------------------------------------------------------------
/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | # Prevent CSRF attacks by raising an exception.
3 | # For APIs, you may want to use :null_session instead.
4 | protect_from_forgery with: :null_session
5 | end
6 |
--------------------------------------------------------------------------------
/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/app/controllers/concerns/.keep
--------------------------------------------------------------------------------
/app/helpers/api/v1/password_resets_helper.rb:
--------------------------------------------------------------------------------
1 | module Api::V1::PasswordResetsHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/sample_helper.rb:
--------------------------------------------------------------------------------
1 | module SampleHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/user_sessions_helper.rb:
--------------------------------------------------------------------------------
1 | module UserSessionsHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/users_helper.rb:
--------------------------------------------------------------------------------
1 | module UsersHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/mailers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/app/mailers/.keep
--------------------------------------------------------------------------------
/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | class ApplicationMailer < ActionMailer::Base
2 | default from: "from@example.com"
3 | layout 'mailer'
4 | end
5 |
--------------------------------------------------------------------------------
/app/mailers/user_mailer.rb:
--------------------------------------------------------------------------------
1 | class UserMailer < ApplicationMailer
2 |
3 | # Subject can be set in your I18n file at config/locales/en.yml
4 | # with the following lookup:
5 | #
6 | # en.user_mailer.reset_password_email.subject
7 | #
8 |
9 | def reset_password_email(user)
10 | @user = User.find user.id
11 | @url = "http://0.0.0.0:8888/path?id=" + @user.reset_password_token
12 | mail(:to => user.email, :subject => "Your password has been reset")
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/models/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/app/models/.keep
--------------------------------------------------------------------------------
/app/models/api_key.rb:
--------------------------------------------------------------------------------
1 | class ApiKey < ActiveRecord::Base
2 | before_create :generate_access_token, :set_expiration, :set_active
3 | belongs_to :user
4 |
5 | def before_expired?
6 | DateTime.now < self.expires_at
7 | end
8 |
9 | def set_active
10 | self.active = true
11 | end
12 |
13 | def set_expiration
14 | self.expires_at = DateTime.now + 1
15 | end
16 |
17 | private
18 |
19 | def generate_access_token
20 | begin
21 | self.access_token = SecureRandom.hex
22 | end while self.class.exists?(access_token: access_token)
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/app/models/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/app/models/concerns/.keep
--------------------------------------------------------------------------------
/app/models/department.rb:
--------------------------------------------------------------------------------
1 | class Department < ActiveRecord::Base
2 | has_many :user_departments
3 |
4 | ADMINISTRATOR = 10
5 | PURCHASE = 20
6 | end
7 |
--------------------------------------------------------------------------------
/app/models/user.rb:
--------------------------------------------------------------------------------
1 | class User < ActiveRecord::Base
2 | authenticates_with_sorcery!
3 |
4 | has_many :api_keys, dependent: :destroy
5 | has_one :user_department, dependent: :destroy
6 |
7 | validates :password, length: { minimum: 3 }
8 | validates :password, confirmation: true
9 | validates :password_confirmation, presence: true
10 |
11 | validates :email, uniqueness: true
12 |
13 | def self.login?(access_token)
14 | api_key = ApiKey.find_by_access_token(access_token)
15 | return false if !api_key || !api_key.before_expired? || !api_key.active
16 | return !self.find(api_key.user_id).nil?
17 | end
18 |
19 | def save_relation(department_params)
20 | if Department.exists?(department_params[:department_id]) && self.save
21 | user_department = UserDepartment.new(user_id: self.id, department_id: department_params[:department_id])
22 | return user_department.save
23 | else
24 | false
25 | end
26 | end
27 |
28 | def update_relation(user_params, department_params)
29 | if Department.exists?(department_params[:department_id]) && self.update(user_params)
30 | return self.user_department.update(department_params)
31 | else
32 | false
33 | end
34 | end
35 |
36 | def activate
37 | if !api_key
38 | return ApiKey.create(user_id: self.id)
39 | else
40 | if !api_key.active
41 | api_key.set_active
42 | api_key.save
43 | end
44 | if !api_key.before_expired?
45 | api_key.set_expiration
46 | api_key.save
47 | end
48 | return api_key
49 | end
50 | end
51 |
52 | def inactivate
53 | api_key.active = false
54 | api_key.save
55 | end
56 |
57 | private
58 |
59 | def api_key
60 | @api_key ||= ApiKey.find_by_user_id(self.id)
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/app/models/user_department.rb:
--------------------------------------------------------------------------------
1 | class UserDepartment < ActiveRecord::Base
2 | belongs_to :user
3 | belongs_to :department
4 | end
5 |
--------------------------------------------------------------------------------
/app/views/api/v1/password_resets/create.html.erb:
--------------------------------------------------------------------------------
1 |
Api::V1::PasswordResets#create
2 | Find me in app/views/api/v1/password_resets/create.html.erb
3 |
--------------------------------------------------------------------------------
/app/views/api/v1/password_resets/edit.html.erb:
--------------------------------------------------------------------------------
1 | Api::V1::PasswordResets#edit
2 | Find me in app/views/api/v1/password_resets/edit.html.erb
3 |
--------------------------------------------------------------------------------
/app/views/api/v1/password_resets/update.html.erb:
--------------------------------------------------------------------------------
1 | Api::V1::PasswordResets#update
2 | Find me in app/views/api/v1/password_resets/update.html.erb
3 |
--------------------------------------------------------------------------------
/app/views/api/v1/sample/admin.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.message @message
--------------------------------------------------------------------------------
/app/views/api/v1/sample/public.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.message @message
--------------------------------------------------------------------------------
/app/views/api/v1/sample/restrict.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.message @message
--------------------------------------------------------------------------------
/app/views/api/v1/user_sessions/create.html.erb:
--------------------------------------------------------------------------------
1 | UserSessions#create
2 | Find me in app/views/user_sessions/create.html.erb
3 |
--------------------------------------------------------------------------------
/app/views/api/v1/user_sessions/create.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.user do |json|
2 | json.id @user.id
3 | json.email @user.email
4 | json.name @user.name
5 | end
6 |
7 | json.access_token @access_token
--------------------------------------------------------------------------------
/app/views/api/v1/user_sessions/destroy.html.erb:
--------------------------------------------------------------------------------
1 | UserSessions#destroy
2 | Find me in app/views/user_sessions/destroy.html.erb
3 |
--------------------------------------------------------------------------------
/app/views/api/v1/user_sessions/new.html.erb:
--------------------------------------------------------------------------------
1 | UserSessions#new
2 | Find me in app/views/user_sessions/new.html.erb
3 |
--------------------------------------------------------------------------------
/app/views/api/v1/users/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.array!(@users) do |user|
2 | json.id user.id
3 | json.email user.email
4 | json.name user.name
5 | end
6 |
--------------------------------------------------------------------------------
/app/views/api/v1/users/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.extract! @user, :id, :email, :name
2 |
3 | json.department do
4 | json.id @user.user_department.department_id
5 | json.name @user.user_department.department.name
6 | end
7 |
--------------------------------------------------------------------------------
/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SorceryApiSample
5 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
6 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
7 | <%= csrf_meta_tags %>
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= yield %>
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/app/views/user_mailer/reset_password_email.text.erb:
--------------------------------------------------------------------------------
1 | Hello, <%= @user.email %>
2 | ===============================================
3 |
4 | You have requested to reset your password.
5 |
6 | To choose a new password, just follow this link: <%= @url %>.
7 |
8 | Have a great day!
--------------------------------------------------------------------------------
/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | begin
3 | load File.expand_path("../spring", __FILE__)
4 | rescue LoadError
5 | end
6 | APP_PATH = File.expand_path('../../config/application', __FILE__)
7 | require_relative '../config/boot'
8 | require 'rails/commands'
9 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | begin
3 | load File.expand_path("../spring", __FILE__)
4 | rescue LoadError
5 | end
6 | require_relative '../config/boot'
7 | require 'rake'
8 | Rake.application.run
9 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'pathname'
3 |
4 | # path to your application root.
5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6 |
7 | Dir.chdir APP_ROOT do
8 | # This script is a starting point to setup your application.
9 | # Add necessary setup steps to this file:
10 |
11 | puts "== Installing dependencies =="
12 | system "gem install bundler --conservative"
13 | system "bundle check || bundle install"
14 |
15 | # puts "\n== Copying sample files =="
16 | # unless File.exist?("config/database.yml")
17 | # system "cp config/database.yml.sample config/database.yml"
18 | # end
19 |
20 | puts "\n== Preparing database =="
21 | system "bin/rake db:setup"
22 |
23 | puts "\n== Removing old logs and tempfiles =="
24 | system "rm -f log/*"
25 | system "rm -rf tmp/cache"
26 |
27 | puts "\n== Restarting application server =="
28 | system "touch tmp/restart.txt"
29 | end
30 |
--------------------------------------------------------------------------------
/bin/spring:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # This file loads spring without using Bundler, in order to be fast.
4 | # It gets overwritten when you run the `spring binstub` command.
5 |
6 | unless defined?(Spring)
7 | require "rubygems"
8 | require "bundler"
9 |
10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)
11 | Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq }
12 | gem "spring", match[1]
13 | require "spring/binstub"
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/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 Rails.application
5 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require "rails"
4 | # Pick the frameworks you want:
5 | require "active_model/railtie"
6 | require "active_job/railtie"
7 | require "active_record/railtie"
8 | require "action_controller/railtie"
9 | require "action_mailer/railtie"
10 | require "action_view/railtie"
11 | require "sprockets/railtie"
12 | # require "rails/test_unit/railtie"
13 |
14 | # Require the gems listed in Gemfile, including any gems
15 | # you've limited to :test, :development, or :production.
16 | Bundler.require(*Rails.groups)
17 |
18 | ENV.update YAML.load_file('config/settings.yml')[Rails.env] rescue {}
19 |
20 | module SorceryApiSample
21 | class Application < Rails::Application
22 | # Settings in config/environments/* take precedence over those specified here.
23 | # Application configuration should go into files in config/initializers
24 | # -- all .rb files in that directory are automatically loaded.
25 |
26 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
27 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
28 | # config.time_zone = 'Central Time (US & Canada)'
29 |
30 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
31 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
32 | # config.i18n.default_locale = :de
33 |
34 | # Do not swallow errors in after_commit/after_rollback callbacks.
35 | config.active_record.raise_in_transactional_callbacks = true
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
2 |
3 | require 'bundler/setup' # Set up gems listed in the Gemfile.
4 |
--------------------------------------------------------------------------------
/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 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: 5
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: db/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: db/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: db/production.sqlite3
26 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Rails.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 | # Do not eager load code on boot.
10 | config.eager_load = false
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 | # Don't care if the mailer can't send.
17 | config.action_mailer.raise_delivery_errors = false
18 |
19 | # Print deprecation notices to the Rails logger.
20 | config.active_support.deprecation = :log
21 |
22 | # Raise an error on page load if there are pending migrations.
23 | config.active_record.migration_error = :page_load
24 |
25 | # Debug mode disables concatenation and preprocessing of assets.
26 | # This option may cause significant delays in view rendering with a large
27 | # number of complex assets.
28 | config.assets.debug = true
29 |
30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets,
31 | # yet still be able to expire them through the digest params.
32 | config.assets.digest = true
33 |
34 | # Adds additional error checking when serving assets at runtime.
35 | # Checks for improperly declared sprockets dependencies.
36 | # Raises helpful error messages.
37 | config.assets.raise_runtime_errors = true
38 |
39 | # Raises error for missing translations
40 | # config.action_view.raise_on_missing_translations = true
41 |
42 | config.action_mailer.delivery_method = :smtp
43 | config.action_mailer.raise_delivery_errors = true
44 | config.action_mailer.smtp_settings = {
45 | :enable_starttls_auto => true,
46 | :address => 'smtp.gmail.com',
47 | :port => '587',
48 | :domain => 'smtp.gmail.com',
49 | :authentication => 'plain',
50 | :user_name => ENV['MAIL_USER'],
51 | :password => ENV['MAIL_PASSWORD'],
52 | :password => ENV['MAIL_APP_PASSWORD']
53 | }
54 | end
55 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Rails.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 | # Eager load code on boot. This eager loads most of Rails and
8 | # your application in memory, allowing both threaded web servers
9 | # and those relying on copy on write to perform better.
10 | # Rake tasks automatically ignore this option for performance.
11 | config.eager_load = true
12 |
13 | # Full error reports are disabled and caching is turned on.
14 | config.consider_all_requests_local = false
15 | config.action_controller.perform_caching = true
16 |
17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application
18 | # Add `rack-cache` to your Gemfile before enabling this.
19 | # For large-scale production use, consider using a caching reverse proxy like
20 | # NGINX, varnish or squid.
21 | # config.action_dispatch.rack_cache = true
22 |
23 | # Disable serving static files from the `/public` folder by default since
24 | # Apache or NGINX already handles this.
25 | config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
26 |
27 | # Compress JavaScripts and CSS.
28 | config.assets.js_compressor = :uglifier
29 | # config.assets.css_compressor = :sass
30 |
31 | # Do not fallback to assets pipeline if a precompiled asset is missed.
32 | config.assets.compile = false
33 |
34 | # Asset digests allow you to set far-future HTTP expiration dates on all assets,
35 | # yet still be able to expire them through the digest params.
36 | config.assets.digest = true
37 |
38 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
39 |
40 | # Specifies the header that your server uses for sending files.
41 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
42 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
43 |
44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
45 | # config.force_ssl = true
46 |
47 | # Use the lowest log level to ensure availability of diagnostic information
48 | # when problems arise.
49 | config.log_level = :debug
50 |
51 | # Prepend all log lines with the following tags.
52 | # config.log_tags = [ :subdomain, :uuid ]
53 |
54 | # Use a different logger for distributed setups.
55 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
56 |
57 | # Use a different cache store in production.
58 | # config.cache_store = :mem_cache_store
59 |
60 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
61 | # config.action_controller.asset_host = 'http://assets.example.com'
62 |
63 | # Ignore bad email addresses and do not raise email delivery errors.
64 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
65 | # config.action_mailer.raise_delivery_errors = false
66 |
67 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
68 | # the I18n.default_locale when a translation cannot be found).
69 | config.i18n.fallbacks = true
70 |
71 | # Send deprecation notices to registered listeners.
72 | config.active_support.deprecation = :notify
73 |
74 | # Use default logging formatter so that PID and timestamp are not suppressed.
75 | config.log_formatter = ::Logger::Formatter.new
76 |
77 | # Do not dump schema after migrations.
78 | config.active_record.dump_schema_after_migration = false
79 | end
80 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Rails.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 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure static file server for tests with Cache-Control for performance.
16 | config.serve_static_files = true
17 | config.static_cache_control = 'public, max-age=3600'
18 |
19 | # Show full error reports and disable caching.
20 | config.consider_all_requests_local = true
21 | config.action_controller.perform_caching = false
22 |
23 | # Raise exceptions instead of rendering exception templates.
24 | config.action_dispatch.show_exceptions = false
25 |
26 | # Disable request forgery protection in test environment.
27 | config.action_controller.allow_forgery_protection = false
28 |
29 | # Tell Action Mailer not to deliver emails to the real world.
30 | # The :test delivery method accumulates sent emails in the
31 | # ActionMailer::Base.deliveries array.
32 | config.action_mailer.delivery_method = :test
33 |
34 | # Randomize the order test cases are executed.
35 | config.active_support.test_order = :random
36 |
37 | # Print deprecation notices to the stderr.
38 | config.active_support.deprecation = :stderr
39 |
40 | # Raises error for missing translations
41 | # config.action_view.raise_on_missing_translations = true
42 |
43 | config.action_mailer.delivery_method = :smtp
44 | config.action_mailer.raise_delivery_errors = true
45 | config.action_mailer.smtp_settings = {
46 | :enable_starttls_auto => true,
47 | :address => 'smtp.gmail.com',
48 | :port => '587',
49 | :domain => 'smtp.gmail.com',
50 | :authentication => 'plain',
51 | :user_name => ENV['MAIL_USER'],
52 | :password => ENV['MAIL_PASSWORD'],
53 | :password => ENV['MAIL_APP_PASSWORD']
54 | }
55 | end
56 |
--------------------------------------------------------------------------------
/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = '1.0'
5 |
6 | # Add additional assets to the asset load path
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 |
9 | # Precompile additional assets.
10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
11 | # Rails.application.config.assets.precompile += %w( search.js )
12 |
--------------------------------------------------------------------------------
/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/cookies_serializer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Rails.application.config.action_dispatch.cookies_serializer = :json
4 |
--------------------------------------------------------------------------------
/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure sensitive parameters which will be filtered from the log file.
4 | Rails.application.config.filter_parameters += [:password]
5 |
--------------------------------------------------------------------------------
/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. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym 'RESTful'
16 | # end
17 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Rails.application.config.session_store :cookie_store, key: '_sorcery_api_sample_session'
4 |
--------------------------------------------------------------------------------
/config/initializers/sorcery.rb:
--------------------------------------------------------------------------------
1 | # The first thing you need to configure is which modules you need in your app.
2 | # The default is nothing which will include only core features (password encryption, login/logout).
3 | # Available submodules are: :user_activation, :http_basic_auth, :remember_me,
4 | # :reset_password, :session_timeout, :brute_force_protection, :activity_logging, :external
5 | Rails.application.config.sorcery.submodules = [:reset_password]
6 |
7 | # Here you can configure each submodule's features.
8 | Rails.application.config.sorcery.configure do |config|
9 | # -- core --
10 | # What controller action to call for non-authenticated users. You can also
11 | # override the 'not_authenticated' method of course.
12 | # Default: `:not_authenticated`
13 | #
14 | # config.not_authenticated_action =
15 |
16 |
17 | # When a non logged in user tries to enter a page that requires login, save
18 | # the URL he wanted to reach, and send him there after login, using 'redirect_back_or_to'.
19 | # Default: `true`
20 | #
21 | # config.save_return_to_url =
22 |
23 |
24 | # Set domain option for cookies; Useful for remember_me submodule.
25 | # Default: `nil`
26 | #
27 | # config.cookie_domain =
28 |
29 |
30 | # Allow the remember_me cookie to be set through AJAX
31 | # Default: `true`
32 | #
33 | # config.remember_me_httponly =
34 |
35 |
36 | # -- session timeout --
37 | # How long in seconds to keep the session alive.
38 | # Default: `3600`
39 | #
40 | # config.session_timeout =
41 |
42 |
43 | # Use the last action as the beginning of session timeout.
44 | # Default: `false`
45 | #
46 | # config.session_timeout_from_last_action =
47 |
48 |
49 | # -- http_basic_auth --
50 | # What realm to display for which controller name. For example {"My App" => "Application"}
51 | # Default: `{"application" => "Application"}`
52 | #
53 | # config.controller_to_realm_map =
54 |
55 |
56 | # -- activity logging --
57 | # will register the time of last user login, every login.
58 | # Default: `true`
59 | #
60 | # config.register_login_time =
61 |
62 |
63 | # will register the time of last user logout, every logout.
64 | # Default: `true`
65 | #
66 | # config.register_logout_time =
67 |
68 |
69 | # will register the time of last user action, every action.
70 | # Default: `true`
71 | #
72 | # config.register_last_activity_time =
73 |
74 |
75 | # -- external --
76 | # What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid, :salesforce] .
77 | # Default: `[]`
78 | #
79 | # config.external_providers =
80 |
81 |
82 | # You can change it by your local ca_file. i.e. '/etc/pki/tls/certs/ca-bundle.crt'
83 | # Path to ca_file. By default use a internal ca-bundle.crt.
84 | # Default: `'path/to/ca_file'`
85 | #
86 | # config.ca_file =
87 |
88 |
89 | # For information about LinkedIn API:
90 | # - user info fields go to https://developer.linkedin.com/documents/profile-fields
91 | # - access permissions go to https://developer.linkedin.com/documents/authentication#granting
92 | #
93 | # config.linkedin.key = ""
94 | # config.linkedin.secret = ""
95 | # config.linkedin.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=linkedin"
96 | # config.linkedin.user_info_fields = ['first-name', 'last-name']
97 | # config.linkedin.user_info_mapping = {first_name: "firstName", last_name: "lastName"}
98 | # config.linkedin.access_permissions = ['r_basicprofile']
99 | #
100 | #
101 | # For information about XING API:
102 | # - user info fields go to https://dev.xing.com/docs/get/users/me
103 | #
104 | # config.xing.key = ""
105 | # config.xing.secret = ""
106 | # config.xing.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=xing"
107 | # config.xing.user_info_mapping = {first_name: "first_name", last_name: "last_name"}
108 | #
109 | #
110 | # Twitter will not accept any requests nor redirect uri containing localhost,
111 | # make sure you use 0.0.0.0:3000 to access your app in development
112 | #
113 | # config.twitter.key = ""
114 | # config.twitter.secret = ""
115 | # config.twitter.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=twitter"
116 | # config.twitter.user_info_mapping = {:email => "screen_name"}
117 | #
118 | # config.facebook.key = ""
119 | # config.facebook.secret = ""
120 | # config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook"
121 | # config.facebook.user_info_mapping = {:email => "name"}
122 | # config.facebook.access_permissions = ["email", "publish_actions"]
123 | # config.facebook.display = "page"
124 | # config.facebook.api_version = "v2.2"
125 | #
126 | # config.github.key = ""
127 | # config.github.secret = ""
128 | # config.github.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=github"
129 | # config.github.user_info_mapping = {:email => "name"}
130 | #
131 | # config.google.key = ""
132 | # config.google.secret = ""
133 | # config.google.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=google"
134 | # config.google.user_info_mapping = {:email => "email", :username => "name"}
135 | #
136 | # config.vk.key = ""
137 | # config.vk.secret = ""
138 | # config.vk.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=vk"
139 | # config.vk.user_info_mapping = {:login => "domain", :name => "full_name"}
140 | #
141 | # To use liveid in development mode you have to replace mydomain.com with
142 | # a valid domain even in development. To use a valid domain in development
143 | # simply add your domain in your /etc/hosts file in front of 127.0.0.1
144 | #
145 | # config.liveid.key = ""
146 | # config.liveid.secret = ""
147 | # config.liveid.callback_url = "http://mydomain.com:3000/oauth/callback?provider=liveid"
148 | # config.liveid.user_info_mapping = {:username => "name"}
149 |
150 | # For information about JIRA API:
151 | # https://developer.atlassian.com/display/JIRADEV/JIRA+REST+API+Example+-+OAuth+authentication
152 | # to obtain the consumer key and the public key you can use the jira-ruby gem https://github.com/sumoheavy/jira-ruby
153 | # or run openssl req -x509 -nodes -newkey rsa:1024 -sha1 -keyout rsakey.pem -out rsacert.pem to obtain the public key
154 | # Make sure you have configured the application link properly
155 |
156 | # config.jira.key = "1234567"
157 | # config.jira.secret = "jiraTest"
158 | # config.jira.site = "http://localhost:2990/jira/plugins/servlet/oauth"
159 | # config.jira.signature_method = "RSA-SHA1"
160 | # config.jira.private_key_file = "rsakey.pem"
161 |
162 | # For information about Salesforce API:
163 | # https://developer.salesforce.com/signup &
164 | # https://www.salesforce.com/us/developer/docs/api_rest/
165 | # Salesforce callback_url must be https. You can run the following to generate self-signed ssl cert
166 | # openssl req -new -newkey rsa:2048 -sha1 -days 365 -nodes -x509 -keyout server.key -out server.crt
167 | # Make sure you have configured the application link properly
168 | # config.salesforce.key = '123123'
169 | # config.salesforce.secret = 'acb123'
170 | # config.salesforce.callback_url = "https://127.0.0.1:9292/oauth/callback?provider=salesforce"
171 | # config.salesforce.scope = "full"
172 | # config.salesforce.user_info_mapping = {:email => "email"}
173 |
174 | # --- user config ---
175 | config.user_config do |user|
176 | # -- core --
177 | # specify username attributes, for example: [:username, :email].
178 | # Default: `[:email]`
179 | #
180 | # user.username_attribute_names =
181 |
182 |
183 | # change *virtual* password attribute, the one which is used until an encrypted one is generated.
184 | # Default: `:password`
185 | #
186 | # user.password_attribute_name =
187 |
188 |
189 | # downcase the username before trying to authenticate, default is false
190 | # Default: `false`
191 | #
192 | # user.downcase_username_before_authenticating =
193 |
194 |
195 | # change default email attribute.
196 | # Default: `:email`
197 | #
198 | # user.email_attribute_name =
199 |
200 |
201 | # change default crypted_password attribute.
202 | # Default: `:crypted_password`
203 | #
204 | # user.crypted_password_attribute_name =
205 |
206 |
207 | # what pattern to use to join the password with the salt
208 | # Default: `""`
209 | #
210 | # user.salt_join_token =
211 |
212 |
213 | # change default salt attribute.
214 | # Default: `:salt`
215 | #
216 | # user.salt_attribute_name =
217 |
218 |
219 | # how many times to apply encryption to the password.
220 | # Default: `nil`
221 | #
222 | # user.stretches =
223 |
224 |
225 | # encryption key used to encrypt reversible encryptions such as AES256.
226 | # WARNING: If used for users' passwords, changing this key will leave passwords undecryptable!
227 | # Default: `nil`
228 | #
229 | # user.encryption_key =
230 |
231 |
232 | # use an external encryption class.
233 | # Default: `nil`
234 | #
235 | # user.custom_encryption_provider =
236 |
237 |
238 | # encryption algorithm name. See 'encryption_algorithm=' for available options.
239 | # Default: `:bcrypt`
240 | #
241 | # user.encryption_algorithm =
242 |
243 |
244 | # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
245 | # Default: `false`
246 | #
247 | # user.subclasses_inherit_config =
248 |
249 |
250 | # -- remember_me --
251 | # How long in seconds the session length will be
252 | # Default: `604800`
253 | #
254 | # user.remember_me_for =
255 |
256 |
257 | # -- user_activation --
258 | # the attribute name to hold activation state (active/pending).
259 | # Default: `:activation_state`
260 | #
261 | # user.activation_state_attribute_name =
262 |
263 |
264 | # the attribute name to hold activation code (sent by email).
265 | # Default: `:activation_token`
266 | #
267 | # user.activation_token_attribute_name =
268 |
269 |
270 | # the attribute name to hold activation code expiration date.
271 | # Default: `:activation_token_expires_at`
272 | #
273 | # user.activation_token_expires_at_attribute_name =
274 |
275 |
276 | # how many seconds before the activation code expires. nil for never expires.
277 | # Default: `nil`
278 | #
279 | # user.activation_token_expiration_period =
280 |
281 |
282 | # your mailer class. Required.
283 | # Default: `nil`
284 | #
285 | # user.user_activation_mailer = UserMailer
286 |
287 |
288 | # when true sorcery will not automatically
289 | # email activation details and allow you to
290 | # manually handle how and when email is sent.
291 | # Default: `false`
292 | #
293 | # user.activation_mailer_disabled =
294 |
295 |
296 | # activation needed email method on your mailer class.
297 | # Default: `:activation_needed_email`
298 | #
299 | # user.activation_needed_email_method_name =
300 |
301 |
302 | # activation success email method on your mailer class.
303 | # Default: `:activation_success_email`
304 | #
305 | # user.activation_success_email_method_name =
306 |
307 |
308 | # do you want to prevent or allow users that did not activate by email to login?
309 | # Default: `true`
310 | #
311 | # user.prevent_non_active_users_to_login =
312 |
313 |
314 | # -- reset_password --
315 | # reset password code attribute name.
316 | # Default: `:reset_password_token`
317 | #
318 | # user.reset_password_token_attribute_name =
319 |
320 |
321 | # expires at attribute name.
322 | # Default: `:reset_password_token_expires_at`
323 | #
324 | # user.reset_password_token_expires_at_attribute_name =
325 |
326 |
327 | # when was email sent, used for hammering protection.
328 | # Default: `:reset_password_email_sent_at`
329 | #
330 | # user.reset_password_email_sent_at_attribute_name =
331 |
332 |
333 | # mailer class. Needed.
334 | # Default: `nil`
335 | #
336 | user.reset_password_mailer = UserMailer
337 |
338 |
339 | # reset password email method on your mailer class.
340 | # Default: `:reset_password_email`
341 | #
342 | # user.reset_password_email_method_name =
343 |
344 |
345 | # when true sorcery will not automatically
346 | # email password reset details and allow you to
347 | # manually handle how and when email is sent
348 | # Default: `false`
349 | #
350 | # user.reset_password_mailer_disabled =
351 |
352 |
353 | # how many seconds before the reset request expires. nil for never expires.
354 | # Default: `nil`
355 | #
356 | # user.reset_password_expiration_period =
357 |
358 |
359 | # hammering protection, how long in seconds to wait before allowing another email to be sent.
360 | # Default: `5 * 60`
361 | #
362 | # user.reset_password_time_between_emails =
363 |
364 |
365 | # -- brute_force_protection --
366 | # Failed logins attribute name.
367 | # Default: `:failed_logins_count`
368 | #
369 | # user.failed_logins_count_attribute_name =
370 |
371 |
372 | # This field indicates whether user is banned and when it will be active again.
373 | # Default: `:lock_expires_at`
374 | #
375 | # user.lock_expires_at_attribute_name =
376 |
377 |
378 | # How many failed logins allowed.
379 | # Default: `50`
380 | #
381 | # user.consecutive_login_retries_amount_limit =
382 |
383 |
384 | # How long the user should be banned. in seconds. 0 for permanent.
385 | # Default: `60 * 60`
386 | #
387 | # user.login_lock_time_period =
388 |
389 | # Unlock token attribute name
390 | # Default: `:unlock_token`
391 | #
392 | # user.unlock_token_attribute_name =
393 |
394 | # Unlock token mailer method
395 | # Default: `:send_unlock_token_email`
396 | #
397 | # user.unlock_token_email_method_name =
398 |
399 | # when true sorcery will not automatically
400 | # send email with unlock token
401 | # Default: `false`
402 | #
403 | # user.unlock_token_mailer_disabled = true
404 |
405 | # Unlock token mailer class
406 | # Default: `nil`
407 | #
408 | # user.unlock_token_mailer = UserMailer
409 |
410 | # -- activity logging --
411 | # Last login attribute name.
412 | # Default: `:last_login_at`
413 | #
414 | # user.last_login_at_attribute_name =
415 |
416 |
417 | # Last logout attribute name.
418 | # Default: `:last_logout_at`
419 | #
420 | # user.last_logout_at_attribute_name =
421 |
422 |
423 | # Last activity attribute name.
424 | # Default: `:last_activity_at`
425 | #
426 | # user.last_activity_at_attribute_name =
427 |
428 |
429 | # How long since last activity is the user defined logged out?
430 | # Default: `10 * 60`
431 | #
432 | # user.activity_timeout =
433 |
434 |
435 | # -- external --
436 | # Class which holds the various external provider data for this user.
437 | # Default: `nil`
438 | #
439 | # user.authentications_class =
440 |
441 |
442 | # User's identifier in authentications class.
443 | # Default: `:user_id`
444 | #
445 | # user.authentications_user_id_attribute_name =
446 |
447 |
448 | # Provider's identifier in authentications class.
449 | # Default: `:provider`
450 | #
451 | # user.provider_attribute_name =
452 |
453 |
454 | # User's external unique identifier in authentications class.
455 | # Default: `:uid`
456 | #
457 | # user.provider_uid_attribute_name =
458 | end
459 |
460 | # This line must come after the 'user config' block.
461 | # Define which model authenticates with sorcery.
462 | config.user_class = "User"
463 | end
464 |
--------------------------------------------------------------------------------
/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] if respond_to?(:wrap_parameters)
9 | end
10 |
11 | # To enable root element in JSON for ActiveRecord objects.
12 | # ActiveSupport.on_load(:active_record) do
13 | # self.include_root_in_json = true
14 | # end
15 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t 'hello'
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t('hello') %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # To learn more, please read the Rails Internationalization guide
20 | # available at http://guides.rubyonrails.org/i18n.html.
21 |
22 | en:
23 | hello: "Hello world"
24 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | # root :to => 'users#index'
3 | # resources :users
4 |
5 | namespace :api do
6 | namespace :v1 do
7 | resources :users
8 | resource :user_sessions, only: [:create, :destroy]
9 | resources :password_resets
10 |
11 | get 'sample/public'
12 | get 'sample/restrict'
13 | get 'sample/admin'
14 | end
15 | end
16 |
17 | # The priority is based upon order of creation: first created -> highest priority.
18 | # See how all your routes lay out with "rake routes".
19 |
20 | # You can have the root of your site routed with "root"
21 | # root 'welcome#index'
22 |
23 | # Example of regular route:
24 | # get 'products/:id' => 'catalog#view'
25 |
26 | # Example of named route that can be invoked with purchase_url(id: product.id)
27 | # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
28 |
29 | # Example resource route (maps HTTP verbs to controller actions automatically):
30 | # resources :products
31 |
32 | # Example resource route with options:
33 | # resources :products do
34 | # member do
35 | # get 'short'
36 | # post 'toggle'
37 | # end
38 | #
39 | # collection do
40 | # get 'sold'
41 | # end
42 | # end
43 |
44 | # Example resource route with sub-resources:
45 | # resources :products do
46 | # resources :comments, :sales
47 | # resource :seller
48 | # end
49 |
50 | # Example resource route with more complex sub-resources:
51 | # resources :products do
52 | # resources :comments
53 | # resources :sales do
54 | # get 'recent', on: :collection
55 | # end
56 | # end
57 |
58 | # Example resource route with concerns:
59 | # concern :toggleable do
60 | # post 'toggle'
61 | # end
62 | # resources :posts, concerns: :toggleable
63 | # resources :photos, concerns: :toggleable
64 |
65 | # Example resource route within a namespace:
66 | # namespace :admin do
67 | # # Directs /admin/products/* to Admin::ProductsController
68 | # # (app/controllers/admin/products_controller.rb)
69 | # resources :products
70 | # end
71 | end
72 |
--------------------------------------------------------------------------------
/config/secrets.yml:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key is used for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 |
6 | # Make sure the secret is at least 30 characters and all random,
7 | # no regular words or you'll be exposed to dictionary attacks.
8 | # You can use `rake secret` to generate a secure secret key.
9 |
10 | # Make sure the secrets in this file are kept private
11 | # if you're sharing your code publicly.
12 |
13 | development:
14 | secret_key_base: 45c7c7c957ad481babcae0bdacbe4921e24afc541ee86874753f142a6e0cf3987fe0939803ba3287c576a8958e6ca3d4ce79fedee3766412a9c347754cd2cf66
15 |
16 | test:
17 | secret_key_base: 192fce17aaf2832f9b25d0961b099ad53dc6c72f9ae679bbb0c8ade35a6c0f596eac06aca9eb358dec17316d29d9ca47221dc98873f134d3dc7abc75a13be92b
18 |
19 | # Do not keep production secrets in the repository,
20 | # instead read values from the environment.
21 | production:
22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
23 |
--------------------------------------------------------------------------------
/db/migrate/20150520221548_sorcery_core.rb:
--------------------------------------------------------------------------------
1 | class SorceryCore < ActiveRecord::Migration
2 | def change
3 | create_table :users do |t|
4 | t.string :email, :null => false
5 | t.string :name, :null => false
6 | t.string :crypted_password
7 | t.string :salt
8 |
9 | t.timestamps
10 | end
11 |
12 | add_index :users, :email, unique: true
13 | end
14 | end
--------------------------------------------------------------------------------
/db/migrate/20150526221756_create_api_keys.rb:
--------------------------------------------------------------------------------
1 | class CreateApiKeys < ActiveRecord::Migration
2 | def change
3 | create_table :api_keys do |t|
4 | t.string :access_token
5 | t.datetime :expires_at
6 | t.integer :user_id
7 |
8 | t.timestamps null: false
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/db/migrate/20150529142034_add_active_api_key.rb:
--------------------------------------------------------------------------------
1 | class AddActiveApiKey < ActiveRecord::Migration
2 | def change
3 | add_column :api_keys, :active, :boolean
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20150607122809_create_user_departments.rb:
--------------------------------------------------------------------------------
1 | class CreateUserDepartments < ActiveRecord::Migration
2 | def change
3 | create_table :user_departments do |t|
4 | t.integer :user_id
5 | t.integer :department_id
6 |
7 | t.timestamps null: false
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20150607134905_create_departments.rb:
--------------------------------------------------------------------------------
1 | class CreateDepartments < ActiveRecord::Migration
2 | def change
3 | create_table :departments do |t|
4 | t.string :name
5 |
6 | t.timestamps null: false
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20150922120215_sorcery_reset_password.rb:
--------------------------------------------------------------------------------
1 | class SorceryResetPassword < ActiveRecord::Migration
2 | def change
3 | add_column :users, :reset_password_token, :string, :default => nil
4 | add_column :users, :reset_password_token_expires_at, :datetime, :default => nil
5 | add_column :users, :reset_password_email_sent_at, :datetime, :default => nil
6 |
7 | add_index :users, :reset_password_token
8 | end
9 | end
--------------------------------------------------------------------------------
/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 that you check this file into your version control system.
13 |
14 | ActiveRecord::Schema.define(version: 20150922120215) do
15 |
16 | create_table "api_keys", force: :cascade do |t|
17 | t.string "access_token"
18 | t.datetime "expires_at"
19 | t.integer "user_id"
20 | t.datetime "created_at", null: false
21 | t.datetime "updated_at", null: false
22 | t.boolean "active"
23 | end
24 |
25 | create_table "departments", force: :cascade do |t|
26 | t.string "name"
27 | t.datetime "created_at", null: false
28 | t.datetime "updated_at", null: false
29 | end
30 |
31 | create_table "user_departments", force: :cascade do |t|
32 | t.integer "user_id"
33 | t.integer "department_id"
34 | t.datetime "created_at", null: false
35 | t.datetime "updated_at", null: false
36 | end
37 |
38 | create_table "users", force: :cascade do |t|
39 | t.string "email", null: false
40 | t.string "name", null: false
41 | t.string "crypted_password"
42 | t.string "salt"
43 | t.datetime "created_at"
44 | t.datetime "updated_at"
45 | t.string "reset_password_token"
46 | t.datetime "reset_password_token_expires_at"
47 | t.datetime "reset_password_email_sent_at"
48 | end
49 |
50 | add_index "users", ["email"], name: "index_users_on_email", unique: true
51 | add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token"
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 |
--------------------------------------------------------------------------------
/lib/assets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/lib/assets/.keep
--------------------------------------------------------------------------------
/lib/tasks/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/lib/tasks/.keep
--------------------------------------------------------------------------------
/log/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/log/.keep
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The page you were looking for doesn't exist.
62 |
You may have mistyped the address or the page may have moved.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The change you wanted was rejected.
62 |
Maybe you tried to change something you didn't have access to.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
We're sorry, but something went wrong.
62 |
63 |
If you are the application owner check the logs for more information.
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SrcHndWng/sorcery_api_sample/b2068216ff6c605d1dc24d5b748996d431732235/public/favicon.ico
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-agent: *
5 | # Disallow: /
6 |
--------------------------------------------------------------------------------
/spec/controllers/password_resets_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe Api::V1::PasswordResetsController, type: :controller do
4 | let(:valid_email) { ENV['MAIL_ADDRESS'] }
5 | let(:non_exist_email) { 'xxx@xxx.com' }
6 |
7 | let(:valid_password_reset_token) { '6pmRCqobTkgrgWAkcQJt' }
8 | let(:non_exist_password_reset_token) { 'xxxxxxxxxx' }
9 |
10 | let(:valid_input) {
11 | {password: 'password', password_confirmation: 'password'}
12 | }
13 | let(:invalid_input) {
14 | {password: 'password', password_confirmation: 'xxxxx'}
15 | }
16 |
17 | before(:all) do
18 | @valid_user = FactoryGirl.create(:user, {email: ENV['MAIL_ADDRESS'], name: 'user1', password: 'password', password_confirmation: 'password'})
19 | @password_reset_user = FactoryGirl.create(:user, {email: 'password@reset.co.jp', name: 'user2', password: 'password', password_confirmation: 'password', reset_password_token: '6pmRCqobTkgrgWAkcQJt'})
20 | end
21 |
22 | after(:all) do
23 | @valid_user.delete
24 | @password_reset_user.delete
25 | end
26 |
27 | describe "POST #create" do
28 | it "returns http success" do
29 | post :create, {format: :json, email: valid_email}
30 |
31 | expect(response.status).to eq(201)
32 | end
33 |
34 | it "non exist email" do
35 | post :create, {format: :json, email: non_exist_email}
36 | expect(response.status).to eq(404)
37 | end
38 | end
39 |
40 | describe "GET #edit" do
41 | it "returns http success" do
42 | get :edit, {format: :json, id: valid_password_reset_token}
43 | expect(response).to have_http_status(200)
44 | end
45 |
46 | it "non exist passoword_reset_token" do
47 | get :edit, {format: :json, id: non_exist_password_reset_token}
48 | expect(response.status).to eq(404)
49 | end
50 | end
51 |
52 | describe "PUT #update" do
53 | it "returns http success" do
54 | put :update, {format: :json, id: valid_password_reset_token, user: valid_input}
55 | expect(response.status).to eq(200)
56 | end
57 |
58 | it "unmatch password, password confirmation" do
59 | put :update, {format: :json, id: valid_password_reset_token, user: invalid_input}
60 | expect(response.status).to eq(406)
61 | end
62 |
63 | it "non exist passoword_reset_token" do
64 | put :update, {format: :json, id: non_exist_password_reset_token, user: valid_input}
65 | expect(response.status).to eq(404)
66 | end
67 | end
68 |
69 | end
70 |
--------------------------------------------------------------------------------
/spec/controllers/sample_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe Api::V1::SampleController, type: :controller do
4 | let(:public_message) { 'public' }
5 | let(:restrict_message) { 'authorized' }
6 | let(:admin_message) { 'admin' }
7 |
8 | before(:all) do
9 | @administration = FactoryGirl.create(:Administration)
10 | @purchase = FactoryGirl.create(:Purchase)
11 |
12 | @user_admin = FactoryGirl.create(:user, {email: 'admin@test.com', name: 'admin', password: 'password', password_confirmation: 'password'})
13 | @user_purchase = FactoryGirl.create(:user, {email: 'purchase@test.com', name: 'purchase', password: 'password', password_confirmation: 'password'})
14 |
15 | @user_admin_api_key = FactoryGirl.create(:api_key, { user_id: @user_admin.id })
16 | @user_purchase_api_key = FactoryGirl.create(:api_key, { user_id: @user_purchase.id })
17 |
18 | @user_admin_department = FactoryGirl.create(
19 | :user_department,
20 | { user_id: @user_admin.id, department_id: @administration.id })
21 | @user_purchase_department = FactoryGirl.create(
22 | :user_department,
23 | { user_id: @user_purchase.id, department_id: @purchase.id })
24 | end
25 |
26 | after(:all) do
27 | @administration.delete
28 | @purchase.delete
29 |
30 | @user_admin.delete
31 | @user_purchase.delete
32 |
33 | @user_admin_api_key.delete
34 | @user_purchase_api_key.delete
35 |
36 | @user_admin_department_department.delete
37 | end
38 |
39 | describe "GET #public" do
40 | context "all user should success" do
41 | it "not login user" do
42 | get :public, { format: :json }
43 | expect(response.status).to eq(200)
44 |
45 | json = JSON.parse(response.body)
46 | expect(json['message']).to eq(public_message)
47 | end
48 |
49 | it "admin user" do
50 | request.env['HTTP_ACCESS_TOKEN'] = @user_admin_api_key.access_token
51 | get :public, { format: :json }
52 | expect(response.status).to eq(200)
53 |
54 | json = JSON.parse(response.body)
55 | expect(json['message']).to eq(public_message)
56 | end
57 |
58 | it "purchase user" do
59 | request.env['HTTP_ACCESS_TOKEN'] = @user_purchase_api_key.access_token
60 | get :public, { format: :json }
61 | expect(response.status).to eq(200)
62 |
63 | json = JSON.parse(response.body)
64 | expect(json['message']).to eq(public_message)
65 | end
66 | end
67 | end
68 |
69 | describe "GET #restrict" do
70 | context "not login user cannot acccess" do
71 | it "not login user" do
72 | get :restrict, { format: :json }
73 | expect(response.status).to eq(401)
74 | expect(response.body.empty?).to eq(true)
75 | end
76 | end
77 |
78 | context "login user success" do
79 | it "admin user" do
80 | request.env['HTTP_ACCESS_TOKEN'] = @user_admin_api_key.access_token
81 | get :restrict, { format: :json }
82 | expect(response.status).to eq(200)
83 |
84 | json = JSON.parse(response.body)
85 | expect(json['message']).to eq(restrict_message)
86 | end
87 |
88 | it "purchase user" do
89 | request.env['HTTP_ACCESS_TOKEN'] = @user_purchase_api_key.access_token
90 | get :restrict, { format: :json }
91 | expect(response.status).to eq(200)
92 |
93 | json = JSON.parse(response.body)
94 | expect(json['message']).to eq(restrict_message)
95 | end
96 | end
97 | end
98 |
99 | describe "GET #admin" do
100 | context "not login user cannot acccess" do
101 | it "not login user" do
102 | get :admin, { format: :json }
103 | expect(response.status).to eq(401)
104 | expect(response.body.empty?).to eq(true)
105 | end
106 | end
107 |
108 | context "purchase user cannnot access" do
109 | it "not admin user" do
110 | request.env['HTTP_ACCESS_TOKEN'] = @user_purchase_api_key.access_token
111 | get :admin, { format: :json }
112 | expect(response.status).to eq(401)
113 | expect(response.body.empty?).to eq(true)
114 | end
115 | end
116 |
117 | context "admin user should success" do
118 | it "admin user" do
119 | request.env['HTTP_ACCESS_TOKEN'] = @user_admin_api_key.access_token
120 | get :admin, { format: :json }
121 | expect(response.status).to eq(200)
122 |
123 | json = JSON.parse(response.body)
124 | expect(json['message']).to eq(admin_message)
125 | end
126 | end
127 | end
128 | end
--------------------------------------------------------------------------------
/spec/controllers/user_sessions_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe Api::V1::UserSessionsController, type: :controller do
4 | let(:valid_login_user) {
5 | {email: 'user1@test.com', password: 'password' }
6 | }
7 | let(:not_exist_login_user) {
8 | {email: 'duke@ggg.com', name: 'duketogo', password: 'x', password_confirmation: 'x'}
9 | }
10 | let(:not_exist_access_token) { 'xxxxx' }
11 |
12 | before(:all) do
13 | @user_1 = FactoryGirl.create(:user, {email: 'user1@test.com', name: 'user1', password: 'password', password_confirmation: 'password'})
14 | @user_2 = FactoryGirl.create(:user, {email: 'user2@test.com', name: 'user2', password: 'password', password_confirmation: 'password'})
15 | @user_3 = FactoryGirl.create(:user, {email: 'user3@test.com', name: 'user3', password: 'password', password_confirmation: 'password'})
16 |
17 | @min_id = User.all[0]['id']
18 | end
19 |
20 | after(:all) do
21 | @user_1.delete
22 | @user_2.delete
23 | @user_3.delete
24 | end
25 |
26 | describe "POST #create" do
27 | it "login success" do
28 | post :create, {format: :json, user: valid_login_user}
29 | expect(response.status).to eq(200)
30 | json = JSON.parse(response.body)
31 | user = json['user']
32 | access_token = json['access_token']
33 | expect(user['id']).to eq(@min_id)
34 | expect(user['email']).to eq('user1@test.com')
35 | expect(user['name']).to eq('user1')
36 | expect(access_token).not_to eq(nil)
37 | end
38 |
39 | it "already login" do
40 | post :create, {format: :json, user: valid_login_user}
41 | expect(response.status).to eq(200)
42 |
43 | post :create, {format: :json, user: valid_login_user}
44 | expect(response.status).to eq(200)
45 | expect(ApiKey.count).to eq(1)
46 | end
47 |
48 | it "api key expired" do
49 | api_key = ApiKey.create(user_id: @min_id)
50 | api_key.expires_at = DateTime.now - 1
51 | api_key.save
52 | expect(api_key.before_expired?).to eq(false)
53 |
54 | post :create, {format: :json, user: valid_login_user}
55 | expect(response.status).to eq(200)
56 | expect(ApiKey.count).to eq(1)
57 | expect(ApiKey.find_by_user_id(@min_id).before_expired?).to eq(true)
58 | end
59 |
60 | it "not exist user" do
61 | post :create, {format: :json, user: not_exist_login_user}
62 | expect(response.status).to eq(404)
63 | end
64 | end
65 |
66 | describe "POST #destroy" do
67 | it "active user" do
68 | post :create, {format: :json, user: valid_login_user}
69 | expect(response.status).to eq(200)
70 | json = JSON.parse(response.body)
71 | user = json['user']
72 | access_token = json['access_token']
73 | expect(ApiKey.find_by_user_id(user['id']).active).to eq(true)
74 |
75 | request.env['HTTP_ACCESS_TOKEN'] = access_token
76 | post :destroy, {format: :json}
77 | expect(response).to have_http_status(200)
78 | expect(ApiKey.find_by_user_id(user['id']).active).to eq(false)
79 | end
80 |
81 | it "not exist access token" do
82 | request.env['HTTP_ACCESS_TOKEN'] = not_exist_access_token
83 | post :destroy, {format: :json}
84 | expect(response).to have_http_status(401)
85 | end
86 | end
87 |
88 | end
89 |
--------------------------------------------------------------------------------
/spec/controllers/users_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe Api::V1::UsersController, type: :controller do
4 | let(:valid_attributes) {
5 | {email: 'duke@ggg.com', name: 'duketogo', password: 'golgo13', password_confirmation: 'golgo13'}
6 | }
7 | let(:invalid_attributes) {
8 | {email: 'duke@ggg.com', name: 'duketogo', password: 'x', password_confirmation: 'x'}
9 | }
10 | let(:administration_department) {
11 | {department_id: 10}
12 | }
13 | let(:purchase_department) {
14 | {department_id: 20}
15 | }
16 | let(:invalid_department) {
17 | {department_id: 13}
18 | }
19 |
20 | before(:all) do
21 | @administration = FactoryGirl.create(:Administration)
22 | @purchase = FactoryGirl.create(:Purchase)
23 |
24 | @user_1 = FactoryGirl.create(:user, {email: 'user1@test.com', name: 'user1', password: 'password', password_confirmation: 'password'})
25 | @user_2 = FactoryGirl.create(:user, {email: 'user2@test.com', name: 'user2', password: 'password', password_confirmation: 'password'})
26 | @user_3 = FactoryGirl.create(:user, {email: 'user3@test.com', name: 'user3', password: 'password', password_confirmation: 'password'})
27 |
28 | @user_1_api_key = FactoryGirl.create(:api_key, { user_id: @user_1.id })
29 | @user_2_api_key = FactoryGirl.create(:api_key, { user_id: @user_2.id })
30 | @user_3_api_key = FactoryGirl.create(:api_key, { user_id: @user_3.id })
31 |
32 | @user_1_department = FactoryGirl.create(
33 | :user_department,
34 | { user_id: @user_1.id, department_id: @administration.id })
35 |
36 | @user_2_department = FactoryGirl.create(
37 | :user_department,
38 | { user_id: @user_2.id, department_id: @administration.id })
39 |
40 | @user_3_department = FactoryGirl.create(
41 | :user_department,
42 | { user_id: @user_3.id, department_id: @purchase.id })
43 |
44 | @min_id = User.all[0]['id']
45 | @user_count = User.count
46 | end
47 |
48 | after(:all) do
49 | @administration.delete
50 | @purchase.delete
51 |
52 | @user_1.delete
53 | @user_2.delete
54 | @user_3.delete
55 |
56 | @user_1_api_key.delete
57 | @user_2_api_key.delete
58 | @user_3_api_key.delete
59 |
60 | @user_1_department.delete
61 | @user_2_department.delete
62 | @user_3_department.delete
63 | end
64 |
65 | describe "GET #index" do
66 | context "get users" do
67 | it "returns users" do
68 | request.env['HTTP_ACCESS_TOKEN'] = @user_1_api_key.access_token
69 | get :index, { format: :json }
70 | expect(response.status).to eq(200)
71 |
72 | json = JSON.parse(response.body)
73 | expect(json.count).to eq(3)
74 | expect(json[0]['id']).to be > 0
75 | expect(json[0]['email']).to eq('user1@test.com')
76 | expect(json[0]['name']).to eq('user1')
77 | end
78 | end
79 | end
80 |
81 | describe "GET #show" do
82 | context "get user" do
83 | it "returns user" do
84 | request.env['HTTP_ACCESS_TOKEN'] = @user_1_api_key.access_token
85 | get :show, { id: @min_id, format: :json }
86 | expect(response.status).to eq(200)
87 |
88 | json = JSON.parse(response.body)
89 | expect(json['id']).to eq(@min_id)
90 | expect(json['email']).to eq('user1@test.com')
91 | expect(json['name']).to eq('user1')
92 | expect(json['department']['id']).to eq(@administration.id)
93 | expect(json['department']['name']).to eq(@administration.name)
94 | end
95 | end
96 |
97 | context "not exists user" do
98 | it "returns nothing" do
99 | request.env['HTTP_ACCESS_TOKEN'] = @user_1_api_key.access_token
100 | not_exist_id = 0
101 | get :show, { id: not_exist_id, format: :json }
102 | expect(response.status).to eq(404)
103 | expect(response.body).to eq("")
104 | end
105 | end
106 | end
107 |
108 | describe "POST #create" do
109 | context "with valid params" do
110 | it "creates a new User" do
111 | expect {
112 | post :create, {format: :json, user: valid_attributes, department: administration_department}
113 | }.to change(User, :count).by(1)
114 |
115 | expect(response.status).to eq(201)
116 |
117 | department = User.all[3].user_department
118 | expect(department[:department_id]).to eq(administration_department[:department_id])
119 | end
120 | end
121 |
122 | context "with invalid params" do
123 | it "header should have bad request" do
124 | expect{
125 | post :create, {format: :json, user: invalid_attributes, department: administration_department}
126 | }.to change(User, :count).by(0)
127 |
128 | expect(response.status).to eq(400)
129 | end
130 | end
131 |
132 | context "with invalid user department" do
133 | it "header should have bad request" do
134 | expect{
135 | post :create, {format: :json, user: valid_attributes, department: invalid_department}
136 | }.to change(User, :count).by(0)
137 |
138 | expect(response.status).to eq(400)
139 | end
140 | end
141 | end
142 |
143 | describe "PUT #update" do
144 | context "with valid params" do
145 | it "update user" do
146 | request.env['HTTP_ACCESS_TOKEN'] = @user_1_api_key.access_token
147 | put :update, { id: @min_id, format: :json, user: valid_attributes, department: purchase_department }
148 | expect(response.status).to eq(200)
149 |
150 | json = JSON.parse(response.body)
151 | expect(json['id']).to eq(@min_id)
152 | expect(json['email']).to eq('duke@ggg.com')
153 | expect(json['name']).to eq('duketogo')
154 | expect(json['department']['id']).to eq(@purchase.id)
155 | expect(json['department']['name']).to eq(@purchase.name)
156 | end
157 | end
158 |
159 | context "with invalid params" do
160 | it "returns error" do
161 | request.env['HTTP_ACCESS_TOKEN'] = @user_1_api_key.access_token
162 | put :update, { id: @min_id, format: :json, user: invalid_attributes, department: purchase_department }
163 | expect(response.status).to eq(422)
164 |
165 | json = JSON.parse(response.body)
166 | expect(json).not_to eq(nil)
167 | end
168 | end
169 |
170 | context "with invalid user department" do
171 | it "header should have bad request" do
172 | request.env['HTTP_ACCESS_TOKEN'] = @user_1_api_key.access_token
173 | put :update, { id: @min_id, format: :json, user: valid_attributes, department: invalid_department }
174 | expect(response.status).to eq(422)
175 |
176 | json = JSON.parse(response.body)
177 | expect(json).not_to eq(nil)
178 | end
179 | end
180 | end
181 |
182 | describe "DELETE #delete" do
183 | context "delete" do
184 | it "delete user" do
185 | request.env['HTTP_ACCESS_TOKEN'] = @user_1_api_key.access_token
186 | delete :destroy, { id: @min_id, format: :json }
187 | expect(response.status).to eq(204)
188 |
189 | expect(User.count).to eq(@user_count - 1)
190 | end
191 | end
192 | end
193 | end
194 |
--------------------------------------------------------------------------------
/spec/factories/api_keys.rb:
--------------------------------------------------------------------------------
1 | FactoryGirl.define do
2 | factory :api_key do
3 | end
4 | end
--------------------------------------------------------------------------------
/spec/factories/department.rb:
--------------------------------------------------------------------------------
1 | FactoryGirl.define do
2 | factory :department do
3 | factory :Administration do
4 | id 10
5 | name "Administration"
6 | end
7 | factory :Purchase do
8 | id 20
9 | name "Purchase"
10 | end
11 | end
12 | end
--------------------------------------------------------------------------------
/spec/factories/user_departments.rb:
--------------------------------------------------------------------------------
1 | FactoryGirl.define do
2 | factory :user_department do
3 | end
4 | end
--------------------------------------------------------------------------------
/spec/factories/users.rb:
--------------------------------------------------------------------------------
1 | FactoryGirl.define do
2 | factory :user do
3 | end
4 | end
--------------------------------------------------------------------------------
/spec/helpers/api/v1/password_resets_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the Api::V1::PasswordResetsHelper. For example:
5 | #
6 | # describe Api::V1::PasswordResetsHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # expect(helper.concat_strings("this","that")).to eq("this that")
10 | # end
11 | # end
12 | # end
13 | RSpec.describe Api::V1::PasswordResetsHelper, type: :helper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/helpers/sample_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the SampleHelper. For example:
5 | #
6 | # describe SampleHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # expect(helper.concat_strings("this","that")).to eq("this that")
10 | # end
11 | # end
12 | # end
13 | RSpec.describe SampleHelper, type: :helper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/helpers/user_sessions_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the UserSessionsHelper. For example:
5 | #
6 | # describe UserSessionsHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # expect(helper.concat_strings("this","that")).to eq("this that")
10 | # end
11 | # end
12 | # end
13 | RSpec.describe UserSessionsHelper, type: :helper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/helpers/users_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the UsersHelper. For example:
5 | #
6 | # describe UsersHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # expect(helper.concat_strings("this","that")).to eq("this that")
10 | # end
11 | # end
12 | # end
13 | RSpec.describe UsersHelper, type: :helper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/mailers/user_mailer_spec.rb:
--------------------------------------------------------------------------------
1 | require "rails_helper"
2 |
3 | RSpec.describe UserMailer, type: :mailer do
4 | describe "reset_password_email" do
5 | let(:mail) { UserMailer.reset_password_email }
6 |
7 | it "renders the headers" do
8 | expect(mail.subject).to eq("Reset password email")
9 | expect(mail.to).to eq(["to@example.org"])
10 | expect(mail.from).to eq(["from@example.com"])
11 | end
12 |
13 | it "renders the body" do
14 | expect(mail.body.encoded).to match("Hi")
15 | end
16 | end
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/spec/models/api_key_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe ApiKey, type: :model do
4 |
5 | end
6 |
--------------------------------------------------------------------------------
/spec/models/department_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe Department, type: :model do
4 | pending "add some examples to (or delete) #{__FILE__}"
5 | end
6 |
--------------------------------------------------------------------------------
/spec/models/user_department_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe UserDepartment, type: :model do
4 | pending "add some examples to (or delete) #{__FILE__}"
5 | end
6 |
--------------------------------------------------------------------------------
/spec/models/user_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe User, type: :model do
4 |
5 | before(:all) do
6 | @no_api_key_user = FactoryGirl.create(:user, {email: 'no_api_key@test.com', name: 'no_api_key', password: 'password', password_confirmation: 'password'})
7 |
8 | @not_activate_user = FactoryGirl.create(:user, {email: 'no_activate_user@test.com', name: 'no_activate_user', password: 'password', password_confirmation: 'password'})
9 | @not_active_api_key = FactoryGirl.create(:api_key, { user_id: @not_activate_user.id })
10 | @not_active_api_key.active = false
11 | @not_active_api_key.save
12 |
13 | @expired_user = FactoryGirl.create(:user, {email: 'expired@test.com', name: 'expired', password: 'password', password_confirmation: 'password'})
14 | @expired_api_key = FactoryGirl.create(:api_key, { user_id: @expired_user.id })
15 | @expired_api_key.expires_at = DateTime.now - 1
16 | @expired_api_key.save
17 |
18 | @active_user = FactoryGirl.create(:user, {email: 'active_user@test.com', name: 'active_user', password: 'password', password_confirmation: 'password'})
19 | @active_api_key = FactoryGirl.create(:api_key, { user_id: @active_user.id })
20 | end
21 |
22 | after(:all) do
23 | @no_api_key_user.delete
24 | @not_activate_user.delete
25 | @not_active_api_key.delete
26 | @expired_user.delete
27 | @expired_api_key.delete
28 | @active_user.delete
29 | @active_api_key.delete
30 | end
31 |
32 | describe "activate" do
33 | it "ApiKey not exist." do
34 | api_key = @no_api_key_user.activate
35 | expect(api_key).not_to eq(nil)
36 | created = ApiKey.find_by_user_id(@no_api_key_user.id)
37 | expect(created.access_token).not_to eq(nil)
38 | expect(created.active).to eq(true)
39 | end
40 |
41 | it "ApiKey exist, not active." do
42 | api_key = @not_activate_user.activate
43 | expect(api_key).not_to eq(nil)
44 | expect(ApiKey.where(user_id: @not_activate_user.id).count).to eq(1)
45 | expect(ApiKey.find_by_user_id(@not_activate_user.id).active).to eq(true)
46 | expect(ApiKey.find_by_user_id(@not_activate_user.id).before_expired?).to eq(true)
47 | end
48 |
49 | it "ApiKey exist, expired." do
50 | api_key = @expired_user.activate
51 | expect(api_key).not_to eq(nil)
52 | expect(ApiKey.where(user_id: @expired_user.id).count).to eq(1)
53 | expect(ApiKey.find_by_user_id(@expired_user.id).active).to eq(true)
54 | expect(ApiKey.find_by_user_id(@expired_user.id).before_expired?).to eq(true)
55 | end
56 | end
57 |
58 | describe "inactivate" do
59 | it "active api key" do
60 | expect(ApiKey.find_by_user_id(@active_user.id).active).to eq(true)
61 | @active_user.inactivate
62 | expect(ApiKey.find_by_user_id(@active_user.id).active).to eq(false)
63 | end
64 | end
65 |
66 | describe "login?" do
67 | it "active user" do
68 | result = User.login?(@active_api_key.access_token)
69 | expect(result).to be(true)
70 | end
71 |
72 | it "not exist access token" do
73 | result = User.login?('9999999999')
74 | expect(result).to be(false)
75 | end
76 |
77 | it "expired user" do
78 | result = User.login?(@expired_api_key.access_token)
79 | expect(result).to be(false)
80 | end
81 |
82 | it "not active user" do
83 | result = User.login?(@not_active_api_key.access_token)
84 | expect(result).to be(false)
85 | end
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/spec/rails_helper.rb:
--------------------------------------------------------------------------------
1 | # This file is copied to spec/ when you run 'rails generate rspec:install'
2 | ENV['RAILS_ENV'] ||= 'test'
3 | require 'spec_helper'
4 | require File.expand_path('../../config/environment', __FILE__)
5 | require 'rspec/rails'
6 | # Add additional requires below this line. Rails is not loaded until this point!
7 |
8 | # Requires supporting ruby files with custom matchers and macros, etc, in
9 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
10 | # run as spec files by default. This means that files in spec/support that end
11 | # in _spec.rb will both be required and run as specs, causing the specs to be
12 | # run twice. It is recommended that you do not name files matching this glob to
13 | # end with _spec.rb. You can configure this pattern with the --pattern
14 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
15 | #
16 | # The following line is provided for convenience purposes. It has the downside
17 | # of increasing the boot-up time by auto-requiring all files in the support
18 | # directory. Alternatively, in the individual `*_spec.rb` files, manually
19 | # require only the support files necessary.
20 | #
21 | # Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
22 |
23 | # Checks for pending migrations before tests are run.
24 | # If you are not using ActiveRecord, you can remove this line.
25 | ActiveRecord::Migration.maintain_test_schema!
26 |
27 | RSpec.configure do |config|
28 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
29 | config.fixture_path = "#{::Rails.root}/spec/fixtures"
30 |
31 | # If you're not using ActiveRecord, or you'd prefer not to run each of your
32 | # examples within a transaction, remove the following line or assign false
33 | # instead of true.
34 | config.use_transactional_fixtures = true
35 |
36 | # RSpec Rails can automatically mix in different behaviours to your tests
37 | # based on their file location, for example enabling you to call `get` and
38 | # `post` in specs under `spec/controllers`.
39 | #
40 | # You can disable this behaviour by removing the line below, and instead
41 | # explicitly tag your specs with their type, e.g.:
42 | #
43 | # RSpec.describe UsersController, :type => :controller do
44 | # # ...
45 | # end
46 | #
47 | # The different available types are documented in the features, such as in
48 | # https://relishapp.com/rspec/rspec-rails/docs
49 | config.infer_spec_type_from_file_location!
50 |
51 | config.render_views = true
52 | end
53 |
--------------------------------------------------------------------------------
/spec/requests/users_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "Users", type: :request do
4 | describe "GET /users" do
5 | it "works! (now write some real specs)" do
6 | get users_path
7 | expect(response).to have_http_status(200)
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/routing/users_routing_spec.rb:
--------------------------------------------------------------------------------
1 | require "rails_helper"
2 |
3 | RSpec.describe UsersController, type: :routing do
4 | describe "routing" do
5 |
6 | it "routes to #index" do
7 | expect(:get => "/users").to route_to("users#index")
8 | end
9 |
10 | it "routes to #new" do
11 | expect(:get => "/users/new").to route_to("users#new")
12 | end
13 |
14 | it "routes to #show" do
15 | expect(:get => "/users/1").to route_to("users#show", :id => "1")
16 | end
17 |
18 | it "routes to #edit" do
19 | expect(:get => "/users/1/edit").to route_to("users#edit", :id => "1")
20 | end
21 |
22 | it "routes to #create" do
23 | expect(:post => "/users").to route_to("users#create")
24 | end
25 |
26 | it "routes to #update" do
27 | expect(:put => "/users/1").to route_to("users#update", :id => "1")
28 | end
29 |
30 | it "routes to #destroy" do
31 | expect(:delete => "/users/1").to route_to("users#destroy", :id => "1")
32 | end
33 |
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # This file was generated by the `rails generate rspec:install` command. Conventionally, all
2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3 | # The generated `.rspec` file contains `--require spec_helper` which will cause
4 | # this file to always be loaded, without a need to explicitly require it in any
5 | # files.
6 | #
7 | # Given that it is always loaded, you are encouraged to keep this file as
8 | # light-weight as possible. Requiring heavyweight dependencies from this file
9 | # will add to the boot time of your test suite on EVERY test run, even for an
10 | # individual file that may not need all of that loaded. Instead, consider making
11 | # a separate helper file that requires the additional dependencies and performs
12 | # the additional setup, and require it from the spec files that actually need
13 | # it.
14 | #
15 | # The `.rspec` file also contains a few flags that are not defaults but that
16 | # users commonly want.
17 | #
18 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19 | RSpec.configure do |config|
20 | # rspec-expectations config goes here. You can use an alternate
21 | # assertion/expectation library such as wrong or the stdlib/minitest
22 | # assertions if you prefer.
23 | config.expect_with :rspec do |expectations|
24 | # This option will default to `true` in RSpec 4. It makes the `description`
25 | # and `failure_message` of custom matchers include text for helper methods
26 | # defined using `chain`, e.g.:
27 | # be_bigger_than(2).and_smaller_than(4).description
28 | # # => "be bigger than 2 and smaller than 4"
29 | # ...rather than:
30 | # # => "be bigger than 2"
31 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true
32 | end
33 |
34 | # rspec-mocks config goes here. You can use an alternate test double
35 | # library (such as bogus or mocha) by changing the `mock_with` option here.
36 | config.mock_with :rspec do |mocks|
37 | # Prevents you from mocking or stubbing a method that does not exist on
38 | # a real object. This is generally recommended, and will default to
39 | # `true` in RSpec 4.
40 | mocks.verify_partial_doubles = true
41 | end
42 |
43 | # The settings below are suggested to provide a good initial experience
44 | # with RSpec, but feel free to customize to your heart's content.
45 | =begin
46 | # These two settings work together to allow you to limit a spec run
47 | # to individual examples or groups you care about by tagging them with
48 | # `:focus` metadata. When nothing is tagged with `:focus`, all examples
49 | # get run.
50 | config.filter_run :focus
51 | config.run_all_when_everything_filtered = true
52 |
53 | # Limits the available syntax to the non-monkey patched syntax that is
54 | # recommended. For more details, see:
55 | # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
56 | # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
57 | # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
58 | config.disable_monkey_patching!
59 |
60 | # Many RSpec users commonly either run the entire suite or an individual
61 | # file, and it's useful to allow more verbose output when running an
62 | # individual spec file.
63 | if config.files_to_run.one?
64 | # Use the documentation formatter for detailed output,
65 | # unless a formatter has already been configured
66 | # (e.g. via a command-line flag).
67 | config.default_formatter = 'doc'
68 | end
69 |
70 | # Print the 10 slowest examples and example groups at the
71 | # end of the spec run, to help surface which specs are running
72 | # particularly slow.
73 | config.profile_examples = 10
74 |
75 | # Run specs in random order to surface order dependencies. If you find an
76 | # order dependency and want to debug it, you can fix the order by providing
77 | # the seed, which is printed after each run.
78 | # --seed 1234
79 | config.order = :random
80 |
81 | # Seed global randomization in this process using the `--seed` CLI option.
82 | # Setting this allows you to use `--seed` to deterministically reproduce
83 | # test failures related to randomization by passing the same `--seed` value
84 | # as the one that triggered the failure.
85 | Kernel.srand config.seed
86 | =end
87 | config.before(:all) do
88 | FactoryGirl.reload
89 | end
90 | end
91 |
--------------------------------------------------------------------------------
/spec/views/sample/public.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "sample/public.html.erb", type: :view do
4 | pending "add some examples to (or delete) #{__FILE__}"
5 | end
6 |
--------------------------------------------------------------------------------
/spec/views/sample/restrict.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "sample/restrict.html.erb", type: :view do
4 | pending "add some examples to (or delete) #{__FILE__}"
5 | end
6 |
--------------------------------------------------------------------------------
/spec/views/user_sessions/create.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "user_sessions/create.html.erb", type: :view do
4 | pending "add some examples to (or delete) #{__FILE__}"
5 | end
6 |
--------------------------------------------------------------------------------
/spec/views/user_sessions/destroy.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "user_sessions/destroy.html.erb", type: :view do
4 | pending "add some examples to (or delete) #{__FILE__}"
5 | end
6 |
--------------------------------------------------------------------------------
/spec/views/user_sessions/new.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "user_sessions/new.html.erb", type: :view do
4 | pending "add some examples to (or delete) #{__FILE__}"
5 | end
6 |
--------------------------------------------------------------------------------
/spec/views/users/edit.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "users/edit", type: :view do
4 | before(:each) do
5 | @user = assign(:user, User.create!(
6 | :email => "MyString",
7 | :name => "MyString",
8 | :crypted_password => "MyString",
9 | :salt => "MyString"
10 | ))
11 | end
12 |
13 | it "renders the edit user form" do
14 | render
15 |
16 | assert_select "form[action=?][method=?]", user_path(@user), "post" do
17 |
18 | assert_select "input#user_email[name=?]", "user[email]"
19 |
20 | assert_select "input#user_name[name=?]", "user[name]"
21 |
22 | assert_select "input#user_crypted_password[name=?]", "user[crypted_password]"
23 |
24 | assert_select "input#user_salt[name=?]", "user[salt]"
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/views/users/index.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "users/index", type: :view do
4 | before(:each) do
5 | assign(:users, [
6 | User.create!(
7 | :email => "Email",
8 | :name => "Name",
9 | :crypted_password => "Crypted Password",
10 | :salt => "Salt"
11 | ),
12 | User.create!(
13 | :email => "Email",
14 | :name => "Name",
15 | :crypted_password => "Crypted Password",
16 | :salt => "Salt"
17 | )
18 | ])
19 | end
20 |
21 | it "renders a list of users" do
22 | render
23 | assert_select "tr>td", :text => "Email".to_s, :count => 2
24 | assert_select "tr>td", :text => "Name".to_s, :count => 2
25 | assert_select "tr>td", :text => "Crypted Password".to_s, :count => 2
26 | assert_select "tr>td", :text => "Salt".to_s, :count => 2
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/spec/views/users/new.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "users/new", type: :view do
4 | before(:each) do
5 | assign(:user, User.new(
6 | :email => "MyString",
7 | :name => "MyString",
8 | :crypted_password => "MyString",
9 | :salt => "MyString"
10 | ))
11 | end
12 |
13 | it "renders new user form" do
14 | render
15 |
16 | assert_select "form[action=?][method=?]", users_path, "post" do
17 |
18 | assert_select "input#user_email[name=?]", "user[email]"
19 |
20 | assert_select "input#user_name[name=?]", "user[name]"
21 |
22 | assert_select "input#user_crypted_password[name=?]", "user[crypted_password]"
23 |
24 | assert_select "input#user_salt[name=?]", "user[salt]"
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/views/users/show.html.erb_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe "users/show", type: :view do
4 | before(:each) do
5 | @user = assign(:user, User.create!(
6 | :email => "Email",
7 | :name => "Name",
8 | :crypted_password => "Crypted Password",
9 | :salt => "Salt"
10 | ))
11 | end
12 |
13 | it "renders attributes in " do
14 | render
15 | expect(rendered).to match(/Email/)
16 | expect(rendered).to match(/Name/)
17 | expect(rendered).to match(/Crypted Password/)
18 | expect(rendered).to match(/Salt/)
19 | end
20 | end
21 |
--------------------------------------------------------------------------------