remotty-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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