remotty-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/Gemfile +18 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +234 -0
  6. data/Rakefile +2 -0
  7. data/app/controllers/remotty/base_application_controller.rb +36 -0
  8. data/app/controllers/remotty/users/base_controller.rb +16 -0
  9. data/app/controllers/remotty/users/confirmations_controller.rb +25 -0
  10. data/app/controllers/remotty/users/omniauth_callbacks_controller.rb +102 -0
  11. data/app/controllers/remotty/users/passwords_controller.rb +47 -0
  12. data/app/controllers/remotty/users/registrations_controller.rb +132 -0
  13. data/app/controllers/remotty/users/sessions_controller.rb +48 -0
  14. data/app/models/remotty/base_user.rb +83 -0
  15. data/app/serializers/remotty/user_serializer.rb +30 -0
  16. data/config/locales/ko.yml +58 -0
  17. data/lib/generators/remotty/rails/install_generator.rb +68 -0
  18. data/lib/generators/remotty/rails/templates/add_column_to_users.rb +42 -0
  19. data/lib/generators/remotty/rails/templates/auth_token.rb +22 -0
  20. data/lib/generators/remotty/rails/templates/create_auth_tokens.rb +28 -0
  21. data/lib/generators/remotty/rails/templates/create_oauth_authentications.rb +28 -0
  22. data/lib/generators/remotty/rails/templates/oauth_authentication.rb +18 -0
  23. data/lib/generators/remotty/rails/templates/paperclip_hash.rb +1 -0
  24. data/lib/generators/remotty/rails/templates/user_serializer.rb +3 -0
  25. data/lib/remotty/rails.rb +8 -0
  26. data/lib/remotty/rails/authentication.rb +6 -0
  27. data/lib/remotty/rails/authentication/json_auth_failure.rb +29 -0
  28. data/lib/remotty/rails/authentication/strategies/token_header_authenticable.rb +71 -0
  29. data/lib/remotty/rails/engine.rb +72 -0
  30. data/lib/remotty/rails/version.rb +5 -0
  31. data/rdoc.sh +3 -0
  32. data/remotty-rails.gemspec +35 -0
  33. metadata +231 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0775052ff14b274bde5cb2946958851c7679d547
4
+ data.tar.gz: 9e29cbf6c8d47dfa73ae6717b985715a790ab400
5
+ SHA512:
6
+ metadata.gz: daba021256deb24ad4492d4f12c9ff94b96d616c989cf8076227c50e432aa990b73a12a49adc04a8619bcd28e98bc13f16bd7923b78138e84b252e8999f48b30
7
+ data.tar.gz: 0a3b34fef53c7a60239b97f0cc47175d371c3092fca263d88cf7a3041832297b9a8f12160a6580b2b44b73861f82310877f79ccf1ca4089a26c44f084e683ca7
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+
24
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in remotty-rails.gemspec
4
+ gemspec
5
+
6
+ gem 'rack-cors', :require => 'rack/cors'
7
+ gem 'active_model_serializers'
8
+
9
+ # Authentication
10
+ gem 'devise'
11
+ gem 'omniauth-facebook'
12
+ gem 'omniauth-twitter'
13
+
14
+ # File upload
15
+ gem 'paperclip'
16
+ gem 'open_uri_redirections'
17
+ gem 'rmagick', require: false
18
+ gem 'fog'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Chungsub Kim
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,234 @@
1
+ # remotty-rails
2
+
3
+ AngularJS + Rails API를 사용할 때 기본적인 셋팅을 도와주어 빠른 초기 셋팅을 가능하게 합니다.
4
+
5
+ ## Description
6
+
7
+ ### 적용사항
8
+
9
+ * header의 token을 이용한 인증처리
10
+ * auth_token model 추가
11
+ * facebook/twitter oauth login
12
+ * oauth_authentication model 추가
13
+ * join
14
+ * email
15
+ * oauth (facebook/twitter)
16
+ * email이 없는 경우도 처리
17
+ * custom devise controller
18
+ * full customizing
19
+ * json response
20
+ * sessions controller
21
+ * registrations controller
22
+ * confirmations controller
23
+ * passwords controller
24
+ * omniauth_callbacks controller
25
+ * user model
26
+ * use avatar for profile image
27
+ * use paperclip for attachment
28
+ * use serializer for json response
29
+ * CORS
30
+ * no cookie/no session
31
+
32
+ ### Token Based Header Authenticable
33
+
34
+ header에 email과 token을 전달하여 인증을 처리함
35
+
36
+ * X-Auth-Email : e-mail
37
+ * X-Auth-Token : auth token
38
+ * X-Auth-Device : source (web(default)/ios/android/...)
39
+ * X-Auth-Device-Info : source info (ip(default)/...)
40
+
41
+ ### JSON format
42
+
43
+ * disable root globally
44
+ * failure default syntax
45
+
46
+ ```json
47
+ {
48
+ "error":{
49
+ "code":"ERROR_CODE",
50
+ "message":"error message"
51
+ }
52
+ }
53
+ ```
54
+
55
+ ### Controller Helper
56
+
57
+ * render_error helper
58
+
59
+ ```ruby
60
+ def render_error(code = 'ERROR', message = '', status = 400)
61
+ render json: {
62
+ error: {
63
+ code: code,
64
+ message: message
65
+ }
66
+ }, :status => status
67
+ end
68
+ ```
69
+
70
+
71
+ ## Library
72
+
73
+ remotty-rails에서 사용중인 라이브러리 입니다.
74
+
75
+ * `rails-api`
76
+ * Rails for API only application (https://github.com/rails-api/rails-api)
77
+ * `active_model_serializers`
78
+ * JSON serialization of objects (https://github.com/rails-api/active_model_serializers)
79
+ * `paperclip`+`rmagick`+`fog`+`httparty`
80
+ * Easy file attachment management (https://github.com/thoughtbot/paperclip)
81
+ * `devise`
82
+ * Flexible authentication solution (https://github.com/plataformatec/devise)
83
+
84
+
85
+ ## Installation
86
+
87
+ * Create Rails API Project
88
+
89
+ ```sh
90
+ $ gem install rails -v 4.0.5 --no-ri --no-rdoc
91
+ $ rails-api new {{project}} --skip-test-unit --skip-sprockets
92
+ ```
93
+
94
+ * Add this line to your application's Gemfile:
95
+
96
+ ```ruby
97
+ gem 'remotty-rails'
98
+ gem 'devise'
99
+ gem 'omniauth-facebook'
100
+ gem 'omniauth-twitter'
101
+ gem 'paperclip'
102
+ ```
103
+
104
+ * And then execute:
105
+
106
+ ```sh
107
+ $ bundle
108
+ ```
109
+
110
+ * install devise
111
+
112
+ ```sh
113
+ $ rails generate devise:install
114
+ $ rails generate devise User
115
+ ```
116
+
117
+ * install remotty-rails
118
+
119
+ `initializers/devise.rb`에서 `config.secret_key` 주석 지우고 작업
120
+
121
+ ```
122
+ $ rails generate remotty:rails:install
123
+ $ rake db:migrate
124
+ ```
125
+
126
+ * `config/routes.rb` update
127
+
128
+ `devise_for :users`를 지우고 추가함
129
+
130
+ ```ruby
131
+ devise_for :users,
132
+ :path => 'api/v1/session',
133
+ :path_names => {
134
+ sign_in: 'login',
135
+ sign_out: 'logout'
136
+ },
137
+ :controllers => { sessions: 'remotty/users/sessions',
138
+ registrations: 'remotty/users/registrations',
139
+ confirmations: 'remotty/users/confirmations',
140
+ passwords: 'remotty/users/passwords',
141
+ omniauth_callbacks: 'remotty/users/omniauth_callbacks'}
142
+ ```
143
+
144
+ ## Recommend Setting
145
+
146
+ ### 유용한 Gemfile
147
+
148
+ `Gemfile` update
149
+
150
+ ```ruby
151
+ group :development do
152
+ gem 'thin'
153
+ gem 'annotate'
154
+ gem 'better_errors'
155
+ gem 'binding_of_caller'
156
+ gem 'letter_opener'
157
+ end
158
+ ```
159
+
160
+ ### sendmail test
161
+
162
+ `development.rb` update
163
+ `letter_opener`는 gem 추가해야함 `gem 'letter_opener'`
164
+
165
+ ```ruby
166
+ config.action_mailer.default_url_options = { host: 'localhost:9000' }
167
+ config.action_mailer.delivery_method = :letter_opener
168
+ ```
169
+
170
+ ### custom mail view
171
+
172
+
173
+ `views/devise/mailer/confirmation_instructions.html.erb` create
174
+ `views/devise/mailer/reset_password_instructions.html.erb` create
175
+
176
+
177
+ ### token 유효기간 변경
178
+
179
+ `initializers/devise.rb` update
180
+
181
+ ```ruby
182
+ config.remember_for = 2.weeks
183
+ ```
184
+
185
+ ### omniauth setting
186
+
187
+ `devise.rb` update
188
+
189
+ ```ruby
190
+ config.omniauth :facebook,
191
+ Settings.omniauth.facebook.app_id,
192
+ Settings.omniauth.facebook.app_secret,
193
+ {
194
+ scope: 'email',
195
+ image_size: 'large',
196
+ provider_ignores_state: true
197
+ }
198
+ config.omniauth :twitter,
199
+ Settings.omniauth.twitter.consumer_key,
200
+ Settings.omniauth.twitter.consumer_secret, {
201
+ :image_size => 'original',
202
+ :authorize_params => {
203
+ :force_login => true
204
+ },
205
+ :setup => lambda do |env|
206
+ req = Rack::Request.new(env)
207
+ req.session.options[:cookie_only] = true
208
+ req.session.options[:defer] = false
209
+ end
210
+ ```
211
+
212
+ ### devise parameter sanitizer
213
+
214
+ user model에 column 추가시 `application_controller.rb` 파일에 추가함
215
+
216
+ ```ruby
217
+ class ApplicationController < ActionController::API
218
+
219
+ protected
220
+
221
+ def configure_permitted_parameters
222
+ devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :email, :password, :current_password, :avatar) }
223
+ devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :avatar, :password, :password_confirmation, :current_password) }
224
+ end
225
+ end
226
+ ```
227
+
228
+ ## Contributing
229
+
230
+ 1. Fork it ( https://github.com/remotty/remotty-rails/fork )
231
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
232
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
233
+ 4. Push to the branch (`git push origin my-new-feature`)
234
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,36 @@
1
+ module Remotty::BaseApplicationController
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ before_action :authenticate_user!
6
+ before_action :configure_permitted_parameters, if: :devise_controller?
7
+
8
+ # To resolve the following error: ActionController::UnknownFormat
9
+ include ActionController::StrongParameters
10
+
11
+ # To resolve the following error: undefined method `respond_to'
12
+ # http://railscasts.com/episodes/348-the-rails-api-gem?language=ko&view=asciicast
13
+ include ActionController::MimeResponds
14
+
15
+ # To resolve the following error: undefined method `default_render'
16
+ # https://github.com/rails-api/rails-api/issues/93
17
+ include ActionController::ImplicitRender
18
+ end
19
+
20
+ protected
21
+
22
+ def render_error(code = 'ERROR', message = '', status = 400)
23
+ render json: {
24
+ error: {
25
+ code: code,
26
+ message: message
27
+ }
28
+ }, :status => status
29
+ end
30
+
31
+ def configure_permitted_parameters
32
+ devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :email, :password, :current_password, :avatar) }
33
+ devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :avatar, :password, :password_confirmation, :current_password) }
34
+ end
35
+
36
+ end
@@ -0,0 +1,16 @@
1
+ # base user controller
2
+ #
3
+ module Remotty::Users::BaseController
4
+ extend ActiveSupport::Concern
5
+
6
+ protected
7
+
8
+ # auth_source 정보 추출 (앱 확장성 고려)
9
+ def auth_source
10
+ {
11
+ source: request.headers['X-Auth-Device'] || 'web',
12
+ info: request.headers['X-Auth-Device-Info'] || request.remote_ip
13
+ }
14
+ end
15
+
16
+ end
@@ -0,0 +1,25 @@
1
+ class Remotty::Users::ConfirmationsController < Devise::ConfirmationsController
2
+ include Remotty::Users::BaseController
3
+
4
+ # POST /resource/confirmation
5
+ # 토큰을 이용해 이메일 인증 확인
6
+ # 이미 사용한 토큰이거나 잘못된 경우는 에러 반환
7
+ #
8
+ # ==== return
9
+ # * +success+ - no_content
10
+ # * +failure+ - unauthorized with error message
11
+ #
12
+ def show
13
+ self.resource = resource_class.confirm_by_token(params[:confirmation_token])
14
+ yield resource if block_given?
15
+
16
+ if resource.errors.empty?
17
+ render nothing: true, status: :no_content
18
+ else
19
+ render_error 'UNAUTHORIZED',
20
+ resource.errors.full_messages.first,
21
+ :unauthorized
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,102 @@
1
+ class Remotty::Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
2
+ include Remotty::Users::BaseController
3
+ include ActionController::Flash
4
+
5
+ # omniauth callback 처리
6
+ # 정보에 따라 유저를 만들던가 연결하던가 추가 정보를 입력받도록 에러를 리턴함
7
+ #
8
+ def all
9
+ # omniauth에서 생성한 session 제거
10
+ session.options[:skip] = true
11
+ response.headers['Set-Cookie'] = 'rack.session=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT'
12
+
13
+ auth = request.env['omniauth.auth']
14
+ user = from_omniauth(auth)
15
+ @ret = {}
16
+
17
+ if user && user.persisted?
18
+ sign_in(:user, user, store: false)
19
+ token = user.generate_auth_token!(auth_source)
20
+ @ret = user.with_token(token)
21
+ elsif user && user.errors.size > 0
22
+ @ret = {
23
+ error: {
24
+ code: 'OAUTH_LOGIN_ERROR_EMAIL_INVALID',
25
+ message: user.errors.full_messages.first,
26
+ data: {
27
+ oauth: {
28
+ credentials: auth[:credentials],
29
+ provider: auth[:provider],
30
+ uid: auth[:uid],
31
+ info: {
32
+ name: auth[:info][:name],
33
+ image: auth[:info][:image]
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ else
40
+ @ret = {
41
+ error: {
42
+ code: 'OAUTH_LOGIN_ERROR',
43
+ message: 'require provider & uid!!'
44
+ }
45
+ }
46
+ @ret[:error][:data] = user if user
47
+ end
48
+
49
+ render :inline => "<script>window.opener.oauthCallback(#{@ret.to_json}); window.close();</script>"
50
+ end
51
+
52
+ def failure
53
+ @ret = {
54
+ error: {
55
+ code: OmniAuth::Utils.camelize(failed_strategy.name),
56
+ message: failure_message
57
+ }
58
+ }
59
+
60
+ render :inline => "<script>window.opener.oauthCallback(#{@ret.to_json}); window.close();</script>"
61
+ end
62
+
63
+ alias_method :facebook, :all
64
+ alias_method :twitter, :all
65
+
66
+ private
67
+
68
+ # omniauth callback 분석
69
+ def from_omniauth(auth)
70
+ if auth[:provider] && auth[:uid] # 인증정보가 있으면..
71
+ oauth = OauthAuthentication.find_by_provider_and_uid(auth[:provider], auth[:uid])
72
+ if oauth # 이미 가입되어 있다면 oauth 정보를 갱신함
73
+ oauth.update_with_credential(auth[:credentials])
74
+ oauth.save
75
+
76
+ return oauth.user
77
+ else # 가입 정보가 없음!
78
+ if auth[:info][:email].present? # 이메일이 있으면 가입 또는 연동
79
+ user = User.find_or_create_by(email: auth[:info][:email]) do |u|
80
+ u.name = auth[:info][:name] || auth[:info][:email]
81
+ u.password = Devise.friendly_token[0,20]
82
+ u.skip_confirmation!
83
+ u.save
84
+ end
85
+ user.confirm! # 인증 대기 중이면 바로 인증시켜버림
86
+
87
+ # oauth 정보 생성
88
+ user.add_oauth_info(auth)
89
+
90
+ return user
91
+ else # 이메일이 없으면 추가정보를 입력받도록 함
92
+ user = User.new
93
+ user.errors.add(:email, "email required")
94
+
95
+ return user
96
+ end
97
+ end
98
+ end
99
+
100
+ nil
101
+ end
102
+ end