jungle_path 0.0.0

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 (129) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +22 -0
  6. data/README.md +5 -0
  7. data/jungle_path.gemspec +43 -0
  8. data/lib/jungle_path/api/helpers/auth.rb +45 -0
  9. data/lib/jungle_path/api/helpers/auth_local_user.rb +284 -0
  10. data/lib/jungle_path/api/helpers/auth_old.rb +232 -0
  11. data/lib/jungle_path/api/helpers/data_cache.rb +20 -0
  12. data/lib/jungle_path/api/helpers/defaults.rb +83 -0
  13. data/lib/jungle_path/api/helpers/logging.rb +36 -0
  14. data/lib/jungle_path/api/helpers/query_filters.rb +15 -0
  15. data/lib/jungle_path/api/helpers/rescues.rb +15 -0
  16. data/lib/jungle_path/api/helpers/result.rb +16 -0
  17. data/lib/jungle_path/api/helpers/standard_apis.rb +280 -0
  18. data/lib/jungle_path/api/helpers.rb +16 -0
  19. data/lib/jungle_path/api/template.erb +35 -0
  20. data/lib/jungle_path/api.rb +5 -0
  21. data/lib/jungle_path/app/a.gitignore +1 -0
  22. data/lib/jungle_path/app/api/server_base.rb +95 -0
  23. data/lib/jungle_path/app/api/server_custom.rb +121 -0
  24. data/lib/jungle_path/app/api/server_gen.rb +11 -0
  25. data/lib/jungle_path/app/auth/authorization.rb +96 -0
  26. data/lib/jungle_path/app/config/a.gitignore +1 -0
  27. data/lib/jungle_path/app/config/config.rb +240 -0
  28. data/lib/jungle_path/app/config/override.rb +3 -0
  29. data/lib/jungle_path/app/config.ru +28 -0
  30. data/lib/jungle_path/app/logs/log_files_go_here +0 -0
  31. data/lib/jungle_path/app/run.sh +4 -0
  32. data/lib/jungle_path/app/schemas/schema.rb +21 -0
  33. data/lib/jungle_path/app/schemas/schema_all_in_one.rb +181 -0
  34. data/lib/jungle_path/app.rb +8 -0
  35. data/lib/jungle_path/authentication/auth_provider/default.rb +83 -0
  36. data/lib/jungle_path/authentication/auth_provider.rb +7 -0
  37. data/lib/jungle_path/authentication/data_provider/default.rb +144 -0
  38. data/lib/jungle_path/authentication/data_provider.rb +7 -0
  39. data/lib/jungle_path/authentication/helpers.rb +19 -0
  40. data/lib/jungle_path/authentication/identity.rb +30 -0
  41. data/lib/jungle_path/authentication/password_hash.rb +124 -0
  42. data/lib/jungle_path/authentication.rb +9 -0
  43. data/lib/jungle_path/authorization/filter.rb +106 -0
  44. data/lib/jungle_path/authorization/paths.rb +71 -0
  45. data/lib/jungle_path/authorization.rb +5 -0
  46. data/lib/jungle_path/cache.rb +36 -0
  47. data/lib/jungle_path/config.rb +65 -0
  48. data/lib/jungle_path/controller/authentication.rb +129 -0
  49. data/lib/jungle_path/controller/base.rb +193 -0
  50. data/lib/jungle_path/controller/helpers.rb +47 -0
  51. data/lib/jungle_path/controller/template.erb +14 -0
  52. data/lib/jungle_path/controller.rb +7 -0
  53. data/lib/jungle_path/db_access/import/db_dir.rb +74 -0
  54. data/lib/jungle_path/db_access/import/delete.rb +30 -0
  55. data/lib/jungle_path/db_access/import/insert.rb +168 -0
  56. data/lib/jungle_path/db_access/import/schema.rb +34 -0
  57. data/lib/jungle_path/db_access/import/select.rb +68 -0
  58. data/lib/jungle_path/db_access/import.rb +15 -0
  59. data/lib/jungle_path/db_access/io/chunked_file_reader.rb +62 -0
  60. data/lib/jungle_path/db_access/io/config.rb +19 -0
  61. data/lib/jungle_path/db_access/io/copy.rb +73 -0
  62. data/lib/jungle_path/db_access/io/db.rb +82 -0
  63. data/lib/jungle_path/db_access/io/delete.rb +23 -0
  64. data/lib/jungle_path/db_access/io/init_db.rb +39 -0
  65. data/lib/jungle_path/db_access/io/insert.rb +24 -0
  66. data/lib/jungle_path/db_access/io/schema.rb +21 -0
  67. data/lib/jungle_path/db_access/io/select.rb +44 -0
  68. data/lib/jungle_path/db_access/io/update.rb +36 -0
  69. data/lib/jungle_path/db_access/io.rb +104 -0
  70. data/lib/jungle_path/db_model/column.rb +186 -0
  71. data/lib/jungle_path/db_model/params.rb +60 -0
  72. data/lib/jungle_path/db_model/schema.rb +100 -0
  73. data/lib/jungle_path/db_model/string.rb +9 -0
  74. data/lib/jungle_path/db_model/table.rb +307 -0
  75. data/lib/jungle_path/db_model.rb +34 -0
  76. data/lib/jungle_path/exceptions.rb +10 -0
  77. data/lib/jungle_path/gen/api.rb +52 -0
  78. data/lib/jungle_path/gen/controller.rb +0 -0
  79. data/lib/jungle_path/gen/db.rb +0 -0
  80. data/lib/jungle_path/gen/schema.rb +47 -0
  81. data/lib/jungle_path/gen/schema_tree/filter.rb +33 -0
  82. data/lib/jungle_path/gen/schema_tree/match_columns.rb +54 -0
  83. data/lib/jungle_path/gen/schema_tree/match_table_data.rb +22 -0
  84. data/lib/jungle_path/gen/schema_tree/match_tables.rb +70 -0
  85. data/lib/jungle_path/gen/schema_tree/node.rb +39 -0
  86. data/lib/jungle_path/gen/schema_tree.rb +105 -0
  87. data/lib/jungle_path/gen.rb +9 -0
  88. data/lib/jungle_path/json/base.rb +29 -0
  89. data/lib/jungle_path/json/time.rb +8 -0
  90. data/lib/jungle_path/json.rb +6 -0
  91. data/lib/jungle_path/logging.rb +23 -0
  92. data/lib/jungle_path/query/alias_info.rb +16 -0
  93. data/lib/jungle_path/query/engine.rb +878 -0
  94. data/lib/jungle_path/query/entity.rb +141 -0
  95. data/lib/jungle_path/query/field.rb +28 -0
  96. data/lib/jungle_path/query/field_primary_key.rb +27 -0
  97. data/lib/jungle_path/query/filter.rb +34 -0
  98. data/lib/jungle_path/query/float_value.rb +16 -0
  99. data/lib/jungle_path/query/from.rb +33 -0
  100. data/lib/jungle_path/query/int_value.rb +16 -0
  101. data/lib/jungle_path/query/limit.rb +19 -0
  102. data/lib/jungle_path/query/nested_hash_sorter.rb +94 -0
  103. data/lib/jungle_path/query/operator.rb +17 -0
  104. data/lib/jungle_path/query/query.rb +23 -0
  105. data/lib/jungle_path/query/sort_field.rb +34 -0
  106. data/lib/jungle_path/query/sql_string.rb +145 -0
  107. data/lib/jungle_path/query/string_value.rb +16 -0
  108. data/lib/jungle_path/query.rb +19 -0
  109. data/lib/jungle_path/rack/basic_credentials.rb +70 -0
  110. data/lib/jungle_path/rack/json_body_parser.rb +41 -0
  111. data/lib/jungle_path/rack.rb +6 -0
  112. data/lib/jungle_path/schema/auth.rb +83 -0
  113. data/lib/jungle_path/schema/base.rb +6 -0
  114. data/lib/jungle_path/schema/db.rb +10 -0
  115. data/lib/jungle_path/schema/version.rb +19 -0
  116. data/lib/jungle_path/schema.rb +8 -0
  117. data/lib/jungle_path/sql/auth_local_user.rb +5 -0
  118. data/lib/jungle_path/sql/general.rb +10 -0
  119. data/lib/jungle_path/sql/helpers.rb +11 -0
  120. data/lib/jungle_path/sql/key.rb +107 -0
  121. data/lib/jungle_path/sql/query_filter.rb +5 -0
  122. data/lib/jungle_path/sql/role.rb +5 -0
  123. data/lib/jungle_path/sql/user.rb +35 -0
  124. data/lib/jungle_path/sql/user_role.rb +5 -0
  125. data/lib/jungle_path/sql.rb +12 -0
  126. data/lib/jungle_path.rb +13 -0
  127. data/test.rb +33 -0
  128. data/test2.rb +15 -0
  129. metadata +200 -0
@@ -0,0 +1,181 @@
1
+ # schema.rb
2
+ require 'jungle_path/db_model'
3
+ require 'jungle_path/schema'
4
+
5
+ module Schema
6
+ # schema meta data:
7
+
8
+ def self.version
9
+ # Specify database version number.
10
+ # This version number will be used to apply database
11
+ # migrations.
12
+ # If the configatron.db.name does not exist, then
13
+ # this schema is applied directly and the appropriate
14
+ # version number is recorded in the database.
15
+ # Version of nil will run all available migrations
16
+ #1
17
+ nil
18
+ end
19
+
20
+ def self.migrations_path
21
+ ::File.expand_path('../ztools/db/migrations',::File.dirname(__FILE__))
22
+ end
23
+
24
+ # base table:
25
+
26
+ class Base < DBModel::Table
27
+ end
28
+
29
+ # Used for database versioning with Sequel migrations:
30
+ class SchemaInfo < Schema::Base
31
+ self.description = "Used by sequel migration."
32
+ define(
33
+ [:version, :integer, :primary_key]
34
+ )
35
+ end
36
+
37
+ # application tables examples:
38
+
39
+ class Answer < Schema::Base
40
+ self.description = ""
41
+ define(
42
+ [:id, :primary_key],
43
+ [:question_id, :foreign_key, :question],
44
+ [:description, :string],
45
+ [:is_correct, :boolean],
46
+ [:audit_user]
47
+ )
48
+ end
49
+
50
+ class Practice < Schema::Base
51
+ self.description = ""
52
+ define(
53
+ [:id, :primary_key],
54
+ [:user_id, :foreign_key, :user],
55
+ [:notes, :string],
56
+ [:random_question_order, :boolean],
57
+ [:random_answer_order, :boolean],
58
+ [:audit_user]
59
+ )
60
+ end
61
+
62
+ class PracticeQuiz < Schema::Base
63
+ self.description = ""
64
+ define(
65
+ [:practice_id, :foreign_key, :practice, :primary_key],
66
+ [:quiz_id, :foreign_key, :quiz, :primary_key],
67
+ [:audit_user]
68
+ )
69
+ def self.plural_table_name
70
+ "practice_quizzes"
71
+ end
72
+ end
73
+
74
+ class PracticeQuestion < Schema::Base
75
+ self.description = ""
76
+ define(
77
+ [:practice_id, :foreign_key, :practice, :primary_key],
78
+ [:question_id, :foreign_key, :question, :primary_key],
79
+ [:note, :string],
80
+ [:audit_user]
81
+ )
82
+ end
83
+
84
+ class PracticeAnswer < Schema::Base
85
+ self.description = ""
86
+ define(
87
+ [:practice_id, :foreign_key, :practice, :primary_key],
88
+ [:answer_id, :foreign_key, :answer, :primary_key],
89
+ [:label, :string],
90
+ [:selected, :boolean],
91
+ [:audit_user]
92
+ )
93
+ end
94
+
95
+ class Question < Schema::Base
96
+ self.description = ""
97
+ define(
98
+ [:id, :primary_key],
99
+ [:quiz_id, :foreign_key, :quiz],
100
+ [:name, :string],
101
+ [:description, :string],
102
+ [:audit_user]
103
+ )
104
+ end
105
+
106
+ class Quiz < Schema::Base
107
+ self.description = ""
108
+ define(
109
+ [:id, :primary_key],
110
+ [:name, :string],
111
+ [:description, :string],
112
+ [:private, :boolean, :default, true],
113
+ [:audit_user]
114
+ )
115
+ def self.plural_table_name
116
+ "quizzes"
117
+ end
118
+ end
119
+
120
+ class Log < Schema::Base
121
+ define(
122
+ [:id, :primary_key],
123
+ [:set_id, :integer],
124
+ [:name, :string],
125
+ [:type, :string],
126
+ [:item, :string, :secure],
127
+ [:timestamp, :timestamp]
128
+ )
129
+ end
130
+
131
+
132
+ class Role < Schema::Base
133
+ self.description = "User authorization: Roles for Users to assume in system."
134
+ define(
135
+ [:id, :primary_key],
136
+ [:name, :string, :unique_index, [:name], :not_null],
137
+ [:description, :string],
138
+ [:audit_user]
139
+ )
140
+ end
141
+
142
+
143
+
144
+ class User < Schema::Base
145
+ self.description = "User of system."
146
+ define(
147
+ [:id, :primary_key],
148
+ [:name, :string, :desc, "Your human name! :)"],
149
+ [:first_name, :string, :index],
150
+ [:last_name, :string, :index],
151
+ [:user_name, :string, :unique, :not_null, :alternate_key, :desc, "may use an email address as a user_name"],
152
+ [:email, :string, :index],
153
+ [:phone, :string, :desc, "mobile phone number", :index],
154
+ [:sms_verification_code, :string, :secure, :desc, "phone verification/sign-in code."],
155
+ [:hash, :string, :not_null, :secure, :calculated, :desc, "See password_hash.rb for details."],
156
+ [:key, :string, :unique, :secure, :calculated, :desc, "Used as alternative to user_name/password."],
157
+ [:activation_key, :string, :secure],
158
+ [:active, :boolean],
159
+ [:is_valid, :boolean, :calculated],
160
+ [:password_reset_code, :string, :secure],
161
+ [:audit_user]
162
+ )
163
+ end
164
+
165
+ class User
166
+ @auth
167
+ @query_filters
168
+ @password
169
+ attr_accessor :auth, :query_filters, :password
170
+ end
171
+
172
+
173
+ class UserRole < Schema::Base
174
+ self.description = "Assign authorization roles to users of system."
175
+ define(
176
+ [:user_id, :foreign_key, :user, :primary_key],
177
+ [:role_id, :foreign_key, :role, :primary_key],
178
+ [:audit_user]
179
+ )
180
+ end
181
+ end
@@ -0,0 +1,8 @@
1
+ module JunglePath
2
+ module App
3
+ def self.sample_config_ru
4
+ end
5
+ def self.sample_run_sh
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,83 @@
1
+ module JunglePath
2
+ module Authentication
3
+ module AuthProvider
4
+ class Default
5
+ def authenticate request, data_provider=nil, no_cache=false
6
+ puts "Auth.authenticate"
7
+ data_provider = JunglePath::Authentication::DataProvider::Default.new unless data_provider
8
+ remote_user = request.env['REMOTE_USER']
9
+ remote_password = request.env['REMOTE_PASSWORD']
10
+ puts "remote_user: #{remote_user}."
11
+ puts "remote_password: #{remote_password}."
12
+ identity = basic_authentication(data_provider, remote_user, remote_password, no_cache)
13
+ identity = basic_authentication(data_provider, remote_user, remote_password, true) unless identity and identity.valid?
14
+ end
15
+
16
+ def basic_authentication data_provider, remote_user, remote_password, no_cache=false
17
+ identity, assume_identity = parse_identities(remote_user, remote_password)
18
+ puts "identity: #{identity}"
19
+ puts "assume_identity: #{assume_identity}"
20
+ valid = false
21
+ identity = authenticate_identity(data_provider, identity, no_cache)
22
+ identity = authorize_identity(data_provider, identity, no_cache)
23
+ assume_identity = authenticate_identity(assume_identity, no_cache) if assume_identity and identity and identity.valid?
24
+ assume_identity = authorize_identity(data_provider, assume_identity, no_cache) if assume_identity
25
+ valid = (assume_identity and assume_identity.valid?) or (identity and identity.valid?)
26
+ return assume_identity if assume_identity
27
+ identity
28
+ end
29
+
30
+ def parse_identities remote_user, remote_password
31
+ identity = JunglePath::Authentication::Identity.new
32
+ identity.remote_user = remote_user
33
+ identity.remote_password = remote_password
34
+ assume_identity = nil
35
+ if remote_user and remote_user.include?("|")
36
+ parts = remote_user.split('|')
37
+ identity.user_name = parts[1]
38
+ assume_identity = JunglePath::Authentication::Identity.new
39
+ assume_identity.user_name = parts[0]
40
+ assume_identity.remote_user = remote_user
41
+ assume_identity.remote_password = remote_password
42
+ else
43
+ identity.user_name = remote_user
44
+ end
45
+ return identity, assume_identity
46
+ end
47
+
48
+ def authenticate_identity data_provider, identity, no_cache=false
49
+ id = nil
50
+ if identity
51
+ id = identity.dup
52
+ id.user = data_provider.get_user(identity.user_name, identity.remote_password, no_cache)
53
+ id.key = id.user
54
+ id.valid = (id.user and id.user.is_valid)
55
+ end
56
+ id
57
+ end
58
+
59
+ def authorize_identity data_provider, identity, no_cache
60
+ id = nil
61
+ if identity
62
+ id = identity.dup
63
+ if id.valid?
64
+ id.roles = data_provider.get_roles(id, no_cache)
65
+ id.default_role = id.roles[0] if id.roles
66
+ id.auth = data_provider.get_auth(id, no_cache)
67
+ id.user.auth = id.auth if id.user
68
+ id.query_filters = data_provider.get_query_filters(id, no_cache)
69
+ else
70
+ id.roles = nil
71
+ id.default_role = nil
72
+ id.auth = nil
73
+ id.user.auth = nil if id.user
74
+ id.query_filters = nil
75
+ end
76
+ end
77
+ id
78
+ end
79
+
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,7 @@
1
+ module JunglePath
2
+ module Authentication
3
+ module AuthProvider
4
+ require 'jungle_path/authentication/auth_provider/default'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,144 @@
1
+ module JunglePath
2
+ require 'jungle_path/authorization/filter'
3
+ module Authentication
4
+ module DataProvider
5
+ class Default
6
+ def initialize models_hash
7
+ @roles = {
8
+ root: {
9
+ id: 0,
10
+ name: :root,
11
+ description: 'root can do anything',
12
+ permissions: [:root],
13
+ restrictions: []
14
+ },
15
+ admin: {
16
+ id: 1,
17
+ name: :admin,
18
+ description: 'admin and add, edit and delete users, but not root users.',
19
+ permissions: [:admin],
20
+ restrictions: []
21
+ },
22
+ user: {
23
+ id: 2,
24
+ name: :user,
25
+ description: 'basic system user -- has read only access.',
26
+ permissions: [:read],
27
+ restrictions: [:query_only, :me_related]
28
+ }
29
+ }
30
+ @users = {
31
+ root: {
32
+ id: 0,
33
+ name: 'root',
34
+ email: nil,
35
+ phone: nil,
36
+ active: true,
37
+ user_name: :root,
38
+ password: 'test',
39
+ roles: [:root]
40
+ },
41
+ admin: {
42
+ id: 1,
43
+ name: 'admin',
44
+ email: nil,
45
+ phone: nil,
46
+ active: true,
47
+ user_name: :admin,
48
+ password: 'test',
49
+ roles: [:admin]
50
+ },
51
+ user: {
52
+ id: 2,
53
+ name: 'user',
54
+ email: nil,
55
+ phone: nil,
56
+ active: true,
57
+ user_name: :user,
58
+ password: 'test',
59
+ roles: [:user]
60
+ }
61
+ }
62
+ @models = models_hash # (parameter models_hash usually from Schema::Base.models)
63
+ @role_permissions = {}
64
+ @role_restrictions = {}
65
+ @roles.each do |role|
66
+ @role_permissions[role.name] = role.permissions
67
+ @role_restrictions[role.name] = role.role_restrictions
68
+ end
69
+ @role_schema_filters = lambda {|identity|
70
+ filters = {
71
+ root: :allow_all_tables,
72
+ admin: :allow_all_tables,
73
+ user: :hide_nonpublic_tables
74
+ }
75
+ }
76
+ @schema_filters = lambda {|identity|
77
+ filters = {
78
+ allow_all_tables: {allow: [table: /./]},
79
+ hide_nonpublic_tables: {allow: [{table: /./}], deny: [{table: /^utility_/}, {table: /^temp_/}]}
80
+ }
81
+ }
82
+ @role_query_filters = lambda {|identity|
83
+ filters = {
84
+ admin: [
85
+ {table_name: :table_i_want_to_filter, sub_select: "select id from table_i_want_to_filter where a = b"}
86
+ ]
87
+ # more...
88
+ }
89
+ }
90
+ @restriction_query_filters = lambda {|identity|
91
+ filters = {
92
+ me_related:[
93
+ {table_name: :user, sub_select: "select id from user where id = #{identity.user.id}"}
94
+ ]
95
+ }
96
+ }
97
+ @user_query_filters = lambda {|identity|
98
+ filters = {}
99
+ }
100
+ end
101
+
102
+ def get_user(user_name, password, no_cache=false)
103
+ lower_case_user_name = nil
104
+ lower_case_user_name = user_name.downcase.to_sym if user_name
105
+ hash = @users[lower_case_user_name]
106
+ user = JunglePath::Schema::User.new(hash, false) if hash
107
+ halt 401, "Unauthorized" unless user
108
+ halt 401, "Unauthorized: user #{user.user_name} is not marked as active." unless user.active
109
+ user.is_valid = (user.password == password)
110
+ user.password = password
111
+ user
112
+ end
113
+
114
+ def get_roles(identity, no_cache=false)
115
+ result = []
116
+ roles = @users[identity.user.user_name.to_sym].roles
117
+ roles.each do |role_symbol|
118
+ role = @roles[role_symbol]
119
+ result << ({id: role[:id], name: role[:name], description: role[:description]})
120
+ end
121
+ result
122
+ end
123
+
124
+ def get_auth(identity, no_cache=false)
125
+ auth = JunglePath::Authorization::Filter.new(identity.roles, @models, @role_permissions, @role_restrictions, @role_schema_filters.call(identity), @schema_filters.call(identity))
126
+ end
127
+
128
+ def get_query_filters(identity, no_cache=false)
129
+ filters = []
130
+ @role_query_filters.call(identity).each do |filter|
131
+ filters << filter
132
+ end
133
+ @restriction_query_filters.call(identity).each do |filter|
134
+ filters << filter
135
+ end
136
+ @user_query_filters.call(identity).each do |filter|
137
+ filters << filter
138
+ end
139
+ filters
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,7 @@
1
+ module JunglePath
2
+ module Authentication
3
+ module DataProvider
4
+ require 'jungle_path/authentication/data_provider/default'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ require 'securerandom'
2
+
3
+ module JunglePath
4
+ module Authentication
5
+ module Helpers
6
+ def self.generate_api_key(prefix="sk_")
7
+ begin
8
+ key = SecureRandom.urlsafe_base64(18)
9
+ end while key.include? ?_
10
+ key = prefix + key
11
+ end
12
+
13
+ def self.expires_in_timestamp(days: 0, hours: 0, minutes: 0, seconds: 0)
14
+ s = seconds + (minutes * 60) + (hours * 60 * 60) + (days * 24 * 60 * 60)
15
+ expires_timestamp = Time.new + s
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ module JunglePath
2
+ module Authentication
3
+ class Identity
4
+ attr_accessor :remote_user, :remote_password, :user_name, :user, :key, :valid, :roles, :default_role, :auth, :query_filters
5
+ def to_s
6
+ "JunglePath::Authentication::Identity: {\n remote_user: #{@remote_user},\n remote_password: #{@remote_password},\n user_name: #{@user_name},\n user: #{@user},\n key: #{@key},\n valid: #{@valid},\n roles: #{@roles},\n auth: #{@auth}\n,query_filters: #{@query_filters}\n}"
7
+ end
8
+ def to_h
9
+ {
10
+ remote_user: @remote_user,
11
+ remote_password: @remote_password,
12
+ user_name: @user_name,
13
+ user: @user,
14
+ key: @key,
15
+ valid: @valid,
16
+ roles: @roles,
17
+ default_role: @default_role,
18
+ auth: @auth,
19
+ query_filters: @query_filters
20
+ }
21
+ end
22
+ def to_hash
23
+ to_h
24
+ end
25
+ def valid?
26
+ @valid
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,124 @@
1
+ # https://crackstation.net/hashing-security.htm#rubysourcecode
2
+ # Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm).
3
+ # Copyright (c) 2013, Taylor Hornby
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # 1. Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ # POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ # Changed 2017-03-30:
29
+ # I wrapped this in jungle_path gem...
30
+ require 'securerandom'
31
+ require 'openssl'
32
+ require 'base64'
33
+
34
+ module JunglePath
35
+ module Authentication
36
+
37
+ # Salted password hashing with PBKDF2-SHA1.
38
+ # Authors: @RedragonX (dicesoft.net), havoc AT defuse.ca
39
+ # www: http://crackstation.net/hashing-security.htm
40
+ module PasswordHash
41
+
42
+ # The following constants can be changed without breaking existing hashes.
43
+ PBKDF2_ITERATIONS = 1000
44
+ SALT_BYTE_SIZE = 24
45
+ HASH_BYTE_SIZE = 24
46
+
47
+ HASH_SECTIONS = 4
48
+ SECTION_DELIMITER = ':'
49
+ ITERATIONS_INDEX = 1
50
+ SALT_INDEX = 2
51
+ HASH_INDEX = 3
52
+
53
+ # Returns a salted PBKDF2 hash of the password.
54
+ def self.createHash( password )
55
+ salt = SecureRandom.base64( SALT_BYTE_SIZE )
56
+ pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac_sha1(
57
+ password,
58
+ salt,
59
+ PBKDF2_ITERATIONS,
60
+ HASH_BYTE_SIZE
61
+ )
62
+ return ["sha1", PBKDF2_ITERATIONS, salt, Base64.encode64( pbkdf2 )].join( SECTION_DELIMITER )
63
+ end
64
+
65
+ # Checks if a password is correct given a hash of the correct one.
66
+ # correctHash must be a hash string generated with createHash.
67
+ def self.validatePassword( password, correctHash )
68
+ params = correctHash.split( SECTION_DELIMITER )
69
+ return false if params.length != HASH_SECTIONS
70
+
71
+ pbkdf2 = Base64.decode64( params[HASH_INDEX] )
72
+ testHash = OpenSSL::PKCS5::pbkdf2_hmac_sha1(
73
+ password,
74
+ params[SALT_INDEX],
75
+ params[ITERATIONS_INDEX].to_i,
76
+ pbkdf2.length
77
+ )
78
+
79
+ return pbkdf2 == testHash
80
+ end
81
+
82
+ # Run tests to ensure the module is functioning properly.
83
+ # Returns true if all tests succeed, false if not.
84
+ def self.runSelfTests
85
+ puts "Sample hashes:"
86
+ 3.times { puts createHash("password") }
87
+
88
+ puts "\nRunning self tests..."
89
+ @@allPass = true
90
+
91
+ correctPassword = 'aaaaaaaaaa'
92
+ wrongPassword = 'aaaaaaaaab'
93
+ hash = createHash(correctPassword)
94
+
95
+ assert( validatePassword( correctPassword, hash ) == true, "correct password" )
96
+ assert( validatePassword( wrongPassword, hash ) == false, "wrong password" )
97
+
98
+ h1 = hash.split( SECTION_DELIMITER )
99
+ h2 = createHash( correctPassword ).split( SECTION_DELIMITER )
100
+ assert( h1[HASH_INDEX] != h2[HASH_INDEX], "different hashes" )
101
+ assert( h1[SALT_INDEX] != h2[SALT_INDEX], "different salt" )
102
+
103
+ if @@allPass
104
+ puts "*** ALL TESTS PASS ***"
105
+ else
106
+ puts "*** FAILURES ***"
107
+ end
108
+
109
+ return @@allPass
110
+ end
111
+
112
+ def self.assert( truth, msg )
113
+ if truth
114
+ puts "PASS [#{msg}]"
115
+ else
116
+ puts "FAIL [#{msg}]"
117
+ @@allPass = false
118
+ end
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ #PasswordHash.runSelfTests
@@ -0,0 +1,9 @@
1
+ module JunglePath
2
+ module Authentication
3
+ require 'jungle_path/authentication/auth_provider'
4
+ require 'jungle_path/authentication/data_provider'
5
+ require 'jungle_path/authentication/helpers'
6
+ require 'jungle_path/authentication/identity'
7
+ require 'jungle_path/authentication/password_hash'
8
+ end
9
+ end