q_auth_ruby_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/q_auth_ruby_client/application.js +13 -0
  6. data/app/assets/stylesheets/q_auth_ruby_client/application.css +15 -0
  7. data/app/controllers/q_auth_ruby_client/application_controller.rb +4 -0
  8. data/app/controllers/q_auth_ruby_client/sessions_controller.rb +50 -0
  9. data/app/helpers/q_auth_ruby_client/api_helper.rb +95 -0
  10. data/app/helpers/q_auth_ruby_client/application_helper.rb +4 -0
  11. data/app/helpers/q_auth_ruby_client/sessions_helper.rb +80 -0
  12. data/app/models/q_auth_ruby_client/user.rb +144 -0
  13. data/app/models/user.rb +2 -0
  14. data/app/views/layouts/q_auth_ruby_client/application.html.erb +14 -0
  15. data/app/views/sessions/sign_in.html.erb +34 -0
  16. data/config/locales/q_auth_ruby_client.en.yml +24 -0
  17. data/config/routes.rb +14 -0
  18. data/db/migrate/20131108102729_create_q_auth_users.rb +46 -0
  19. data/lib/q_auth_ruby_client.rb +20 -0
  20. data/lib/q_auth_ruby_client/configuration.rb +29 -0
  21. data/lib/q_auth_ruby_client/engine.rb +5 -0
  22. data/lib/q_auth_ruby_client/version.rb +3 -0
  23. data/lib/tasks/q_auth_ruby_client_tasks.rake +4 -0
  24. data/test/dummy/README.rdoc +28 -0
  25. data/test/dummy/Rakefile +6 -0
  26. data/test/dummy/app/assets/javascripts/application.js +13 -0
  27. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  28. data/test/dummy/app/controllers/application_controller.rb +5 -0
  29. data/test/dummy/app/helpers/application_helper.rb +2 -0
  30. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/test/dummy/bin/bundle +3 -0
  32. data/test/dummy/bin/rails +4 -0
  33. data/test/dummy/bin/rake +4 -0
  34. data/test/dummy/config.ru +4 -0
  35. data/test/dummy/config/application.rb +23 -0
  36. data/test/dummy/config/boot.rb +5 -0
  37. data/test/dummy/config/database.yml +25 -0
  38. data/test/dummy/config/environment.rb +5 -0
  39. data/test/dummy/config/environments/development.rb +37 -0
  40. data/test/dummy/config/environments/production.rb +78 -0
  41. data/test/dummy/config/environments/test.rb +39 -0
  42. data/test/dummy/config/initializers/assets.rb +8 -0
  43. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  44. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  45. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  46. data/test/dummy/config/initializers/inflections.rb +16 -0
  47. data/test/dummy/config/initializers/mime_types.rb +4 -0
  48. data/test/dummy/config/initializers/session_store.rb +3 -0
  49. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/test/dummy/config/locales/en.yml +23 -0
  51. data/test/dummy/config/routes.rb +4 -0
  52. data/test/dummy/config/secrets.yml +22 -0
  53. data/test/dummy/public/404.html +67 -0
  54. data/test/dummy/public/422.html +67 -0
  55. data/test/dummy/public/500.html +66 -0
  56. data/test/dummy/public/favicon.ico +0 -0
  57. data/test/integration/navigation_test.rb +10 -0
  58. data/test/q_auth_ruby_client_test.rb +7 -0
  59. data/test/test_helper.rb +19 -0
  60. metadata +200 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 54889974ab4b1501ecec98963f77fa44e6524ce3
4
+ data.tar.gz: 545ebc4561cf6ddac0cecc9d1859fe97fb6173bd
5
+ SHA512:
6
+ metadata.gz: e527814f327a25804bfe059d7ba8cf30114f7541f5c8c9909aa32889f8ac7b5af96d766b0e294ab6f18d321829c60b3a0ab581705d794b7da2ce41269d919b91
7
+ data.tar.gz: 3244975e235415c363656c4939f9cac311da91760985842190508aa21ba28df2401ca5d6312701116849797b85cafea295f9355a78ce3dace693582e18fbbb82
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = QAuthRubyClient
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'QAuthRubyClient'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the 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
+ */
@@ -0,0 +1,4 @@
1
+ module QAuthRubyClient
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,50 @@
1
+ class QAuthRubyClient::SessionsController < ApplicationController
2
+
3
+ before_filter :require_user, :only => :sign_out
4
+ before_filter :set_navs
5
+
6
+ def sign_in
7
+ if current_user
8
+ if current_user.token_expired?
9
+ update_user_profile_data_and_auth_token
10
+ return
11
+ else
12
+ redirect_to redirect_url_after_sign_in
13
+ return
14
+ end
15
+ else
16
+ update_user_profile_data_and_auth_token
17
+ return
18
+ end
19
+ end
20
+
21
+ def create_session
22
+ response = QAuthRubyClient::User.create_session(params[:auth_token])
23
+ if response.is_a?(QAuthRubyClient::User)
24
+ @current_user = response
25
+ session[:id] = @current_user.q_auth_uid unless session[:id]
26
+ set_notification_messages(I18n.t("authentication.logged_in_successfully_heading"), I18n.t("authentication.logged_in_successfully_message"), :success)
27
+ redirect_to default_redirect_url_after_sign_in
28
+ else
29
+ raise response["errors"]["name"]
30
+ end
31
+ end
32
+
33
+ def sign_out
34
+
35
+ store_flash_message("You have successfully signed out", :notice)
36
+
37
+ # Reseting the auth token for user when he logs out.
38
+ # @current_user.update_attribute :auth_token, SecureRandom.hex
39
+
40
+ session.delete(:id)
41
+
42
+ redirect_to default_redirect_url_after_sign_out
43
+ end
44
+
45
+ private
46
+
47
+ def set_navs
48
+ set_nav("Login")
49
+ end
50
+ end
@@ -0,0 +1,95 @@
1
+ module QAuthRubyClient
2
+ module ApiHelper
3
+ include ActionController::HttpAuthentication::Token::ControllerMethods
4
+
5
+ def current_user
6
+ # Return if @current_user is already initialized else check if the user exists with the auth token present in request header
7
+ @current_user ||= authenticate_with_http_token { |token, options| QAuthRubyClient::User.find_by(auth_token: token)}
8
+ end
9
+
10
+ def require_auth_token
11
+ current_user
12
+ unless @current_user
13
+ proc_code = Proc.new do
14
+ set_notification_messages(I18n.t("response.error"), I18n.t("response.authentication_error"), :error)
15
+ raise AuthenticationError
16
+ end
17
+ render_json_response(proc_code)
18
+ return
19
+ end
20
+ end
21
+
22
+ def require_super_admin_auth_token
23
+ current_user
24
+ unless @current_user && @current_user.is_super_admin?
25
+ proc_code = Proc.new do
26
+ set_notification_messages(I18n.t("response.error"), I18n.t("response.authentication_error"), :error)
27
+ raise AuthenticationError
28
+ end
29
+ render_json_response(proc_code)
30
+ return
31
+ end
32
+ end
33
+
34
+ def require_admin_auth_token
35
+ current_user
36
+ unless @current_user && @current_user.is_admin?
37
+ proc_code = Proc.new do
38
+ set_notification_messages(I18n.t("response.error"), I18n.t("response.authentication_error"), :error)
39
+ raise AuthenticationError
40
+ end
41
+ render_json_response(proc_code)
42
+ return
43
+ end
44
+ end
45
+
46
+ def embed_stack_in_json_response?
47
+ ["true", "t", "1", "yes"].include?(params[:debug].to_s.downcase.strip) # || Rails.env == "development"
48
+ end
49
+
50
+ ## This method will accept a proc, execute it and render the json
51
+ def render_json_response(proc_code)
52
+
53
+ begin
54
+ proc_code.call
55
+ @status ||= 200
56
+ @success = @success == false ? (false) : (true)
57
+
58
+ rescue ValidationError, InvalidLoginError, FailedToCreateError, FailedToUpdateError, FailedToDeleteError, AuthenticationError => e
59
+ @status = 200
60
+ @success = false
61
+
62
+ @data = {
63
+ errors: {
64
+ name: e.message,
65
+ description: I18n.translate("response.#{e.message.underscore}")
66
+ }
67
+ }
68
+ @data[:errors][:details] = @errors unless @errors.blank?
69
+ @data[:errors][:stack] = e.backtrace if embed_stack_in_json_response?
70
+
71
+ rescue Exception => e
72
+
73
+ @data = {
74
+ errors: {
75
+ name: e.message,
76
+ description: I18n.translate("response.#{e.message.underscore}"),
77
+ details: @errors
78
+ }
79
+ }
80
+ @data[:errors][:stack] = e.backtrace if embed_stack_in_json_response?
81
+
82
+ end
83
+
84
+ response_hash = {success: @success}
85
+ response_hash[:alert] = @alert unless @alert.blank?
86
+ response_hash[:total_data] = @total_data unless @total_data.blank?
87
+ response_hash[:per_page] = @per_page unless @per_page.blank?
88
+ response_hash[:current_page] = @current_page unless @current_page.blank?
89
+ response_hash[:data] = @data unless @data.blank?
90
+
91
+ render status: @status, json: response_hash
92
+ return
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,4 @@
1
+ module QAuthRubyClient
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,80 @@
1
+ module QAuthRubyClient
2
+ module SessionsHelper
3
+
4
+ # Returns the default URL to which the system should redirect the user after successful authentication
5
+ def default_redirect_url_after_sign_in
6
+ QAuthRubyClient.configuration.default_redirect_url_after_sign_in
7
+ end
8
+
9
+ # Returns the default URL to which the system should redirect after the user successfully logout
10
+ def default_redirect_url_after_sign_out
11
+ QAuthRubyClient.configuration.default_redirect_url_after_sign_out
12
+ end
13
+
14
+ def redirect_url_after_sign_in
15
+ params[:redirect_back_url] || default_redirect_url_after_sign_in
16
+ end
17
+
18
+ def redirect_to_sign_in_page
19
+ respond_to do |format|
20
+ format.html {
21
+ redirect_to q_auth_ruby_client.sign_in_path
22
+ }
23
+ format.json { render json: {heading: @heading, alert: @alert} }
24
+ format.js { render(:partial => 'sessions/redirect.js.erb', :handlers => [:erb], :formats => [:js]) }
25
+ end
26
+ end
27
+
28
+ def update_user_profile_data_and_auth_token
29
+ # Store the user object and Redirect to the Q-Auth sign in page with required params
30
+ params_hsh = {client_app: QAuthRubyClient.configuration.q_app_name, redirect_back_url: create_session_url}
31
+ url = add_query_params(QAuthRubyClient.configuration.q_auth_url, params_hsh)
32
+ redirect_to url
33
+ end
34
+
35
+ # This method is widely used to create the @current_user object from the session
36
+ # This method will return @current_user if it already exists which will save queries when called multiple times
37
+ def current_user
38
+ session[:qarc] = "true"
39
+ return @current_user if @current_user
40
+ # Check if the user exists with the auth token present in session
41
+ @current_user = QAuthRubyClient::User.where("q_auth_uid = ?", session[:id]).first
42
+ end
43
+
44
+ # This method is usually used as a before filter to secure some of the actions which requires the user to be signed in.
45
+ def require_user
46
+ current_user
47
+ if @current_user
48
+ if @current_user.token_expired?
49
+ @current_user = nil
50
+ session.delete(:id)
51
+ set_notification_messages(I18n.t("authentication.session_expired_heading"), I18n.t("authentication.session_expired_message"), :error)
52
+ redirect_to_sign_in_page
53
+ return
54
+ end
55
+ else
56
+ set_notification_messages(I18n.t("authentication.permission_denied_heading"), I18n.t("authentication.permission_denied_message"), :error)
57
+ redirect_to_sign_in_page
58
+ return
59
+ end
60
+ end
61
+
62
+ # This method is usually used as a before filter from admin controllers to ensure that the logged in user is an admin
63
+ def require_admin
64
+ unless @current_user.is_admin?
65
+ set_notification_messages(I18n.t("authentication.permission_denied_heading"), I18n.t("authentication.permission_denied_message"), :error)
66
+ redirect_to_sign_in_page
67
+ return
68
+ end
69
+ end
70
+
71
+ # This method is usually used as a before filter from admin controllers to ensure that the logged in user is a super admin
72
+ def require_super_admin
73
+ unless @current_user.is_super_admin?
74
+ set_notification_messages(I18n.t("authentication.permission_denied_heading"), I18n.t("authentication.permission_denied_message"), :error)
75
+ redirect_to_sign_in_page
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,144 @@
1
+ class QAuthRubyClient::User < ActiveRecord::Base
2
+
3
+ require 'typhoeus'
4
+
5
+ self.table_name = 'users'
6
+
7
+ def self.fetch_all_users(auth_token)
8
+ qauth_url = QAuthRubyClient.configuration.q_auth_url + "/api/v1/members"
9
+ request = Typhoeus::Request.new(
10
+ qauth_url,
11
+ method: :get,
12
+ headers: {"Authorization" => "Token token=#{auth_token}"},
13
+ verbose: false
14
+ )
15
+ response = JSON.parse(request.run.body)
16
+
17
+ if response["success"]
18
+ response['data'].each do |data|
19
+ user = find_in_cache(data)
20
+ user.update_cache(data)
21
+ end
22
+ else
23
+ raise
24
+ end
25
+ end
26
+
27
+ def self.find_in_cache(data)
28
+ # Checking if we already have this user(s) in our database
29
+ users = QAuthRubyClient::User.where("auth_token = ? or username = ? or email = ? or q_auth_uid = ?", data['auth_token'], data['username'], data['email'], data['id']).all
30
+
31
+ # Get the first user
32
+ user = users.first
33
+
34
+ if user
35
+ # Corner Case : If there are (by chance) multiple rows, we need to remove them.
36
+ users.delete(user)
37
+ users.destroy_all if users.count > 0
38
+ return user
39
+ else
40
+ # Create a new user
41
+ QAuthRubyClient::User.new(auth_token: data['auth_token'], username: data['username'], email: data['email'], q_auth_uid: data['id'])
42
+ end
43
+ end
44
+
45
+ def update_cache(data)
46
+ self.name = data["name"]
47
+ self.biography = data["biography"]
48
+ self.phone = data["phone"]
49
+ self.skype = data["skype"]
50
+ self.linkedin = data["linkedin"]
51
+ self.city = data["city"]
52
+ self.state = data["state"]
53
+ self.country = data["country"]
54
+
55
+ self.token_created_at = data["token_created_at"] || Time.now - 1.day
56
+ self.user_type = data["user_type"]
57
+
58
+ self.thumb_url = data.try(:[],"profile_image").try(:[],"thumb")
59
+ self.medium_url = data.try(:[],"profile_image").try(:[],"medium")
60
+ self.large_url = data.try(:[],"profile_image").try(:[],"large")
61
+ self.original_url = data.try(:[],"profile_image").try(:[],"original")
62
+
63
+ self.designation = data.try(:[],"designation").try(:[],"title")
64
+ self.department = data.try(:[],"department").try(:[],"name")
65
+
66
+ self.save if self.valid?
67
+ end
68
+
69
+ def self.create_session(auth_token)
70
+ qauth_url = QAuthRubyClient.configuration.q_auth_url + "/api/v1/my_profile"
71
+ request = Typhoeus::Request.new(
72
+ qauth_url,
73
+ method: :get,
74
+ headers: {"Authorization" => "Token token=#{auth_token}"},
75
+ verbose: false
76
+ )
77
+ response = JSON.parse(request.run.body)
78
+
79
+ if response["success"]
80
+ user = find_in_cache(response['data'])
81
+ user.update_cache(response['data'])
82
+ return user
83
+ else
84
+ return response
85
+ end
86
+ end
87
+
88
+ def token_expired?
89
+ return self.token_created_at.nil? || (Time.now > self.token_created_at + QAuthRubyClient.configuration.session_time_out)
90
+ end
91
+
92
+ # * Return address which includes city, state & country
93
+ # == Examples
94
+ # >>> user.display_address
95
+ # => "Mysore, Karnataka, India"
96
+ def display_address
97
+ address_list = []
98
+ address_list << city unless city.blank?
99
+ address_list << state unless state.blank?
100
+ address_list << country unless country.blank?
101
+ address_list.join(", ")
102
+ end
103
+
104
+ # * Return true if the user is either a Q-Auth Super Admin or Q-Auth Admin
105
+ # == Examples
106
+ # >>> user.is_admin?
107
+ # => true
108
+ def is_admin?
109
+ user_type == 'admin' || user_type == 'super_admin'
110
+ end
111
+
112
+ # * Return true if the user is either a Q-Auth Admin
113
+ # == Examples
114
+ # >>> user.is_super_admin?
115
+ # => true
116
+ def is_super_admin?
117
+ user_type == 'super_admin'
118
+ end
119
+
120
+ # * Return true if the user is not activated, else false.
121
+ # * inactive status will be there only for users who are not activated by user
122
+ # == Examples
123
+ # >>> user.inactive?
124
+ # => true
125
+ def inactive?
126
+ (status == "inactive")
127
+ end
128
+
129
+ # * Return true if the user is activated, else false.
130
+ # == Examples
131
+ # >>> user.active?
132
+ # => true
133
+ def active?
134
+ (status == "active")
135
+ end
136
+
137
+ # * Return true if the user is suspended, else false.
138
+ # == Examples
139
+ # >>> user.suspended?
140
+ # => true
141
+ def suspended?
142
+ (status == "suspended")
143
+ end
144
+ end