cbsorcery 0.8.6

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 (135) hide show
  1. data/.document +5 -0
  2. data/.gitignore +56 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +40 -0
  5. data/CHANGELOG.md +263 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +360 -0
  9. data/Rakefile +6 -0
  10. data/gemfiles/active_record-rails40.gemfile +7 -0
  11. data/gemfiles/active_record-rails41.gemfile +7 -0
  12. data/lib/generators/sorcery/USAGE +22 -0
  13. data/lib/generators/sorcery/helpers.rb +40 -0
  14. data/lib/generators/sorcery/install_generator.rb +95 -0
  15. data/lib/generators/sorcery/templates/initializer.rb +451 -0
  16. data/lib/generators/sorcery/templates/migration/activity_logging.rb +10 -0
  17. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +9 -0
  18. data/lib/generators/sorcery/templates/migration/core.rb +13 -0
  19. data/lib/generators/sorcery/templates/migration/external.rb +12 -0
  20. data/lib/generators/sorcery/templates/migration/remember_me.rb +8 -0
  21. data/lib/generators/sorcery/templates/migration/reset_password.rb +9 -0
  22. data/lib/generators/sorcery/templates/migration/user_activation.rb +9 -0
  23. data/lib/sorcery.rb +85 -0
  24. data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
  25. data/lib/sorcery/adapters/base_adapter.rb +30 -0
  26. data/lib/sorcery/controller.rb +157 -0
  27. data/lib/sorcery/controller/config.rb +65 -0
  28. data/lib/sorcery/controller/submodules/activity_logging.rb +82 -0
  29. data/lib/sorcery/controller/submodules/brute_force_protection.rb +38 -0
  30. data/lib/sorcery/controller/submodules/external.rb +199 -0
  31. data/lib/sorcery/controller/submodules/http_basic_auth.rb +74 -0
  32. data/lib/sorcery/controller/submodules/remember_me.rb +81 -0
  33. data/lib/sorcery/controller/submodules/session_timeout.rb +56 -0
  34. data/lib/sorcery/crypto_providers/aes256.rb +51 -0
  35. data/lib/sorcery/crypto_providers/bcrypt.rb +97 -0
  36. data/lib/sorcery/crypto_providers/common.rb +35 -0
  37. data/lib/sorcery/crypto_providers/md5.rb +19 -0
  38. data/lib/sorcery/crypto_providers/sha1.rb +28 -0
  39. data/lib/sorcery/crypto_providers/sha256.rb +36 -0
  40. data/lib/sorcery/crypto_providers/sha512.rb +36 -0
  41. data/lib/sorcery/engine.rb +21 -0
  42. data/lib/sorcery/model.rb +183 -0
  43. data/lib/sorcery/model/config.rb +96 -0
  44. data/lib/sorcery/model/submodules/activity_logging.rb +70 -0
  45. data/lib/sorcery/model/submodules/brute_force_protection.rb +125 -0
  46. data/lib/sorcery/model/submodules/external.rb +100 -0
  47. data/lib/sorcery/model/submodules/remember_me.rb +62 -0
  48. data/lib/sorcery/model/submodules/reset_password.rb +131 -0
  49. data/lib/sorcery/model/submodules/user_activation.rb +149 -0
  50. data/lib/sorcery/model/temporary_token.rb +30 -0
  51. data/lib/sorcery/protocols/certs/ca-bundle.crt +5182 -0
  52. data/lib/sorcery/protocols/oauth.rb +42 -0
  53. data/lib/sorcery/protocols/oauth2.rb +47 -0
  54. data/lib/sorcery/providers/base.rb +27 -0
  55. data/lib/sorcery/providers/facebook.rb +63 -0
  56. data/lib/sorcery/providers/github.rb +51 -0
  57. data/lib/sorcery/providers/google.rb +51 -0
  58. data/lib/sorcery/providers/jira.rb +77 -0
  59. data/lib/sorcery/providers/linkedin.rb +66 -0
  60. data/lib/sorcery/providers/liveid.rb +53 -0
  61. data/lib/sorcery/providers/twitter.rb +59 -0
  62. data/lib/sorcery/providers/vk.rb +63 -0
  63. data/lib/sorcery/providers/xing.rb +64 -0
  64. data/lib/sorcery/railties/tasks.rake +6 -0
  65. data/lib/sorcery/test_helpers/internal.rb +78 -0
  66. data/lib/sorcery/test_helpers/internal/rails.rb +68 -0
  67. data/lib/sorcery/test_helpers/rails/controller.rb +21 -0
  68. data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
  69. data/lib/sorcery/version.rb +3 -0
  70. data/sorcery.gemspec +34 -0
  71. data/spec/active_record/user_activation_spec.rb +18 -0
  72. data/spec/active_record/user_activity_logging_spec.rb +17 -0
  73. data/spec/active_record/user_brute_force_protection_spec.rb +16 -0
  74. data/spec/active_record/user_oauth_spec.rb +16 -0
  75. data/spec/active_record/user_remember_me_spec.rb +16 -0
  76. data/spec/active_record/user_reset_password_spec.rb +16 -0
  77. data/spec/active_record/user_spec.rb +37 -0
  78. data/spec/controllers/controller_activity_logging_spec.rb +124 -0
  79. data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
  80. data/spec/controllers/controller_http_basic_auth_spec.rb +68 -0
  81. data/spec/controllers/controller_oauth2_spec.rb +407 -0
  82. data/spec/controllers/controller_oauth_spec.rb +240 -0
  83. data/spec/controllers/controller_remember_me_spec.rb +117 -0
  84. data/spec/controllers/controller_session_timeout_spec.rb +80 -0
  85. data/spec/controllers/controller_spec.rb +215 -0
  86. data/spec/orm/active_record.rb +21 -0
  87. data/spec/rails_app/app/active_record/authentication.rb +3 -0
  88. data/spec/rails_app/app/active_record/user.rb +5 -0
  89. data/spec/rails_app/app/active_record/user_provider.rb +3 -0
  90. data/spec/rails_app/app/controllers/sorcery_controller.rb +265 -0
  91. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  92. data/spec/rails_app/app/mailers/sorcery_mailer.rb +32 -0
  93. data/spec/rails_app/app/views/application/index.html.erb +17 -0
  94. data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
  95. data/spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  96. data/spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  97. data/spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb +17 -0
  98. data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  99. data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  100. data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  101. data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  102. data/spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
  103. data/spec/rails_app/config.ru +4 -0
  104. data/spec/rails_app/config/application.rb +56 -0
  105. data/spec/rails_app/config/boot.rb +4 -0
  106. data/spec/rails_app/config/database.yml +22 -0
  107. data/spec/rails_app/config/environment.rb +5 -0
  108. data/spec/rails_app/config/environments/test.rb +37 -0
  109. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  110. data/spec/rails_app/config/initializers/inflections.rb +10 -0
  111. data/spec/rails_app/config/initializers/mime_types.rb +5 -0
  112. data/spec/rails_app/config/initializers/secret_token.rb +7 -0
  113. data/spec/rails_app/config/initializers/session_store.rb +12 -0
  114. data/spec/rails_app/config/locales/en.yml +5 -0
  115. data/spec/rails_app/config/routes.rb +48 -0
  116. data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
  117. data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +19 -0
  118. data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +13 -0
  119. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +16 -0
  120. data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +22 -0
  121. data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  122. data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  123. data/spec/rails_app/db/schema.rb +23 -0
  124. data/spec/rails_app/db/seeds.rb +7 -0
  125. data/spec/shared_examples/user_activation_shared_examples.rb +242 -0
  126. data/spec/shared_examples/user_activity_logging_shared_examples.rb +97 -0
  127. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +156 -0
  128. data/spec/shared_examples/user_oauth_shared_examples.rb +36 -0
  129. data/spec/shared_examples/user_remember_me_shared_examples.rb +57 -0
  130. data/spec/shared_examples/user_reset_password_shared_examples.rb +263 -0
  131. data/spec/shared_examples/user_shared_examples.rb +467 -0
  132. data/spec/sorcery_crypto_providers_spec.rb +198 -0
  133. data/spec/spec.opts +2 -0
  134. data/spec/spec_helper.rb +41 -0
  135. metadata +350 -0
@@ -0,0 +1,81 @@
1
+ module Sorcery
2
+ module Controller
3
+ module Submodules
4
+ # The Remember Me submodule takes care of setting the user's cookie so that he will
5
+ # be automatically logged in to the site on every visit,
6
+ # until the cookie expires.
7
+ # See Sorcery::Model::Submodules::RememberMe for configuration options.
8
+ module RememberMe
9
+ def self.included(base)
10
+ base.send(:include, InstanceMethods)
11
+ Config.module_eval do
12
+ class << self
13
+ attr_accessor :remember_me_httponly
14
+ def merge_remember_me_defaults!
15
+ @defaults.merge!(:@remember_me_httponly => true)
16
+ end
17
+ end
18
+ merge_remember_me_defaults!
19
+ end
20
+ Config.login_sources << :login_from_cookie
21
+ Config.after_login << :remember_me_if_asked_to
22
+ Config.after_logout << :forget_me!
23
+ end
24
+
25
+ module InstanceMethods
26
+ # This method sets the cookie and calls the user to save the token and the expiration to db.
27
+ def remember_me!
28
+ current_user.remember_me!
29
+ set_remember_me_cookie!(current_user)
30
+ end
31
+
32
+ # Clears the cookie and clears the token from the db.
33
+ def forget_me!
34
+ current_user.forget_me!
35
+ cookies.delete(:remember_me_token, :domain => Config.cookie_domain)
36
+ end
37
+
38
+ # Override.
39
+ # logins a user instance, and optionally remembers him.
40
+ def auto_login(user, should_remember = false)
41
+ session[:user_id] = user.id.to_s
42
+ @current_user = user
43
+ remember_me! if should_remember
44
+ end
45
+
46
+ protected
47
+
48
+ # calls remember_me! if a third credential was passed to the login method.
49
+ # Runs as a hook after login.
50
+ def remember_me_if_asked_to(user, credentials)
51
+ remember_me! if ( credentials.size == 3 && credentials[2] && credentials[2] != "0" )
52
+ end
53
+
54
+ # Checks the cookie for a remember me token, tried to find a user with that token
55
+ # and logs the user in if found.
56
+ # Runs as a login source. See 'current_user' method for how it is used.
57
+ def login_from_cookie
58
+ user = cookies.signed[:remember_me_token] && user_class.sorcery_adapter.find_by_remember_me_token(cookies.signed[:remember_me_token])
59
+ if user && user.has_remember_me_token?
60
+ set_remember_me_cookie!(user)
61
+ session[:user_id] = user.id.to_s
62
+ @current_user = user
63
+ else
64
+ @current_user = false
65
+ end
66
+ end
67
+
68
+ def set_remember_me_cookie!(user)
69
+ cookies.signed[:remember_me_token] = {
70
+ :value => user.send(user.sorcery_config.remember_me_token_attribute_name),
71
+ :expires => user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name),
72
+ :httponly => Config.remember_me_httponly,
73
+ :domain => Config.cookie_domain
74
+ }
75
+ end
76
+ end
77
+
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,56 @@
1
+ module Sorcery
2
+ module Controller
3
+ module Submodules
4
+ # This submodule helps you set a timeout to all user sessions.
5
+ # The timeout can be configured and also you can choose to reset it on every user action.
6
+ module SessionTimeout
7
+ def self.included(base)
8
+ base.send(:include, InstanceMethods)
9
+ Config.module_eval do
10
+ class << self
11
+ attr_accessor :session_timeout, # how long in seconds to keep the session alive.
12
+
13
+ :session_timeout_from_last_action # use the last action as the beginning of session
14
+ # timeout.
15
+
16
+ def merge_session_timeout_defaults!
17
+ @defaults.merge!(:@session_timeout => 3600, # 1.hour
18
+ :@session_timeout_from_last_action => false)
19
+ end
20
+ end
21
+ merge_session_timeout_defaults!
22
+ end
23
+ Config.after_login << :register_login_time
24
+ base.prepend_before_filter :validate_session
25
+ end
26
+
27
+ module InstanceMethods
28
+ protected
29
+
30
+ # Registers last login to be used as the timeout starting point.
31
+ # Runs as a hook after a successful login.
32
+ def register_login_time(user, credentials)
33
+ session[:login_time] = session[:last_action_time] = Time.now.in_time_zone
34
+ end
35
+
36
+ # Checks if session timeout was reached and expires the current session if so.
37
+ # To be used as a before_filter, before require_login
38
+ def validate_session
39
+ session_to_use = Config.session_timeout_from_last_action ? session[:last_action_time] : session[:login_time]
40
+ if session_to_use && sorcery_session_expired?(session_to_use.to_time)
41
+ reset_sorcery_session
42
+ @current_user = nil
43
+ else
44
+ session[:last_action_time] = Time.now.in_time_zone
45
+ end
46
+ end
47
+
48
+ def sorcery_session_expired?(time)
49
+ Time.now.in_time_zone - time > Config.session_timeout
50
+ end
51
+
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,51 @@
1
+ require "openssl"
2
+
3
+ module Sorcery
4
+ module CryptoProviders
5
+ # This encryption method is reversible if you have the supplied key.
6
+ # So in order to use this encryption method you must supply it with a key first.
7
+ # In an initializer, or before your application initializes, you should do the following:
8
+ #
9
+ # Sorcery::Model::ConfigAES256.key = "my 32 bytes long key"
10
+ #
11
+ # My final comment is that this is a strong encryption method,
12
+ # but its main weakness is that its reversible. If you do not need to reverse the hash
13
+ # then you should consider Sha512 or BCrypt instead.
14
+ #
15
+ # Keep your key in a safe place, some even say the key should be stored on a separate server.
16
+ # This won't hurt performance because the only time it will try and access the key on the
17
+ # separate server is during initialization, which only
18
+ # happens once. The reasoning behind this is if someone does compromise your server they
19
+ # won't have the key also. Basically, you don't want to store the key with the lock.
20
+ class AES256
21
+ class << self
22
+ attr_writer :key
23
+
24
+ def encrypt(*tokens)
25
+ aes.encrypt
26
+ aes.key = @key
27
+ [aes.update(tokens.join) + aes.final].pack("m").chomp
28
+ end
29
+
30
+ def matches?(crypted, *tokens)
31
+ decrypt(crypted) == tokens.join
32
+ rescue OpenSSL::CipherError
33
+ false
34
+ end
35
+
36
+ def decrypt(crypted)
37
+ aes.decrypt
38
+ aes.key = @key
39
+ (aes.update(crypted.unpack("m").first) + aes.final)
40
+ end
41
+
42
+ private
43
+
44
+ def aes
45
+ raise ArgumentError.new("#{name} expects a 32 bytes long key. Please use Sorcery::Model::Config.encryption_key to set it.") if ( @key.nil? || @key == "" )
46
+ @aes ||= OpenSSL::Cipher::Cipher.new("AES-256-ECB")
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,97 @@
1
+ require 'bcrypt'
2
+
3
+ module Sorcery
4
+ module CryptoProviders
5
+ # For most apps Sha512 is plenty secure, but if you are building an app that stores nuclear
6
+ # launch codes you might want to consier BCrypt. This is an extremely
7
+ # secure hashing algorithm, mainly because it is slow.
8
+ # A brute force attack on a BCrypt encrypted password would take much longer than a brute force attack on a
9
+ # password encrypted with a Sha algorithm. Keep in mind you are sacrificing performance by using this,
10
+ # generating a password takes exponentially longer than any
11
+ # of the Sha algorithms. I did some benchmarking to save you some time with your decision:
12
+ #
13
+ # require "bcrypt"
14
+ # require "digest"
15
+ # require "benchmark"
16
+ #
17
+ # Benchmark.bm(18) do |x|
18
+ # x.report("BCrypt (cost = 10:") { 100.times { BCrypt::Password.create("mypass", :cost => 10) } }
19
+ # x.report("BCrypt (cost = 2:") { 100.times { BCrypt::Password.create("mypass", :cost => 2) } }
20
+ # x.report("Sha512:") { 100.times { Digest::SHA512.hexdigest("mypass") } }
21
+ # x.report("Sha1:") { 100.times { Digest::SHA1.hexdigest("mypass") } }
22
+ # end
23
+ #
24
+ # user system total real
25
+ # BCrypt (cost = 10): 10.780000 0.060000 10.840000 ( 11.100289)
26
+ # BCrypt (cost = 2): 0.180000 0.000000 0.180000 ( 0.181914)
27
+ # Sha512: 0.000000 0.000000 0.000000 ( 0.000829)
28
+ # Sha1: 0.000000 0.000000 0.000000 ( 0.000395)
29
+ #
30
+ # You can play around with the cost to get that perfect balance between performance and security.
31
+ #
32
+ # Decided BCrypt is for you? Just insall the bcrypt gem:
33
+ #
34
+ # gem install bcrypt-ruby
35
+ #
36
+ # Update your initializer to use it:
37
+ #
38
+ # config.encryption_algorithm = :bcrypt
39
+ #
40
+ # You are good to go!
41
+ class BCrypt
42
+ class << self
43
+ # This is the :cost option for the BCrpyt library.
44
+ # The higher the cost the more secure it is and the longer is take the generate a hash. By default this is 10.
45
+ # Set this to whatever you want, play around with it to get that perfect balance between
46
+ # security and performance.
47
+ def cost
48
+ @cost ||= 10
49
+ end
50
+ attr_writer :cost
51
+ alias :stretches :cost
52
+ alias :stretches= :cost=
53
+
54
+ # Creates a BCrypt hash for the password passed.
55
+ def encrypt(*tokens)
56
+ ::BCrypt::Password.create(join_tokens(tokens), :cost => cost)
57
+ end
58
+
59
+ # Does the hash match the tokens? Uses the same tokens that were used to encrypt.
60
+ def matches?(hash, *tokens)
61
+ hash = new_from_hash(hash)
62
+ return false if hash.nil? || hash == {}
63
+ hash == join_tokens(tokens)
64
+ end
65
+
66
+ # This method is used as a flag to tell Sorcery to "resave" the password
67
+ # upon a successful login, using the new cost
68
+ def cost_matches?(hash)
69
+ hash = new_from_hash(hash)
70
+ if hash.nil? || hash == {}
71
+ false
72
+ else
73
+ hash.cost == cost
74
+ end
75
+ end
76
+
77
+ def reset!
78
+ @cost = 10
79
+ end
80
+
81
+ private
82
+
83
+ def join_tokens(tokens)
84
+ tokens.flatten.join
85
+ end
86
+
87
+ def new_from_hash(hash)
88
+ begin
89
+ ::BCrypt::Password.new(hash)
90
+ rescue ::BCrypt::Errors::InvalidHash
91
+ return nil
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,35 @@
1
+ module Sorcery
2
+ module CryptoProviders
3
+ module Common
4
+ def self.included(base)
5
+ base.class_eval do
6
+ class << self
7
+ attr_accessor :join_token
8
+
9
+ # The number of times to loop through the encryption.
10
+ def stretches
11
+ @stretches ||= 1
12
+ end
13
+ attr_writer :stretches
14
+
15
+ def encrypt(*tokens)
16
+ digest = tokens.flatten.compact.join(join_token)
17
+ stretches.times { digest = secure_digest(digest) }
18
+ digest
19
+ end
20
+
21
+ # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
22
+ def matches?(crypted, *tokens)
23
+ encrypt(*tokens.compact) == crypted
24
+ end
25
+
26
+ def reset!
27
+ @stretches = 1
28
+ @join_token = nil
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ require "digest/md5"
2
+
3
+ module Sorcery
4
+ module CryptoProviders
5
+ # This class was made for the users transitioning from md5 based systems.
6
+ # I highly discourage using this crypto provider as it superbly inferior
7
+ # to your other options.
8
+ #
9
+ # Please use any other provider offered by Sorcery.
10
+ class MD5
11
+ include Common
12
+ class << self
13
+ def secure_digest(digest)
14
+ Digest::MD5.hexdigest(digest)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ require "digest/sha1"
2
+
3
+ module Sorcery
4
+ module CryptoProviders
5
+ # This class was made for the users transitioning from restful_authentication. I highly discourage using this
6
+ # crypto provider as it inferior to your other options. Please use any other provider offered by Sorcery.
7
+ class SHA1
8
+ include Common
9
+ class << self
10
+ def join_token
11
+ @join_token ||= "--"
12
+ end
13
+
14
+ # Turns your raw password into a Sha1 hash.
15
+ def encrypt(*tokens)
16
+ tokens = tokens.flatten
17
+ digest = tokens.shift
18
+ stretches.times { digest = secure_digest([digest, *tokens].join(join_token)) }
19
+ digest
20
+ end
21
+
22
+ def secure_digest(digest)
23
+ Digest::SHA1.hexdigest(digest)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ require "digest/sha2"
2
+
3
+ module Sorcery
4
+ # The activate_sorcery method has a custom_crypto_provider configuration option.
5
+ # This allows you to use any type of encryption you like.
6
+ # Just create a class with a class level encrypt and matches? method. See example below.
7
+ #
8
+ # === Example
9
+ #
10
+ # class MyAwesomeEncryptionMethod
11
+ # def self.encrypt(*tokens)
12
+ # # the tokens passed will be an array of objects, what type of object is irrelevant,
13
+ # # just do what you need to do with them and return a single encrypted string.
14
+ # # for example, you will most likely join all of the objects into a single string and then encrypt that string
15
+ # end
16
+ #
17
+ # def self.matches?(crypted, *tokens)
18
+ # # return true if the crypted string matches the tokens.
19
+ # # depending on your algorithm you might decrypt the string then compare it to the token, or you might
20
+ # # encrypt the tokens and make sure it matches the crypted string, its up to you
21
+ # end
22
+ # end
23
+ module CryptoProviders
24
+ # = Sha256
25
+ #
26
+ # Uses the Sha256 hash algorithm to encrypt passwords.
27
+ class SHA256
28
+ include Common
29
+ class << self
30
+ def secure_digest(digest)
31
+ Digest::SHA256.hexdigest(digest)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ require "digest/sha2"
2
+
3
+ module Sorcery
4
+ # The activate_sorcery method has a custom_crypto_provider configuration option.
5
+ # This allows you to use any type of encryption you like.
6
+ # Just create a class with a class level encrypt and matches? method. See example below.
7
+ #
8
+ # === Example
9
+ #
10
+ # class MyAwesomeEncryptionMethod
11
+ # def self.encrypt(*tokens)
12
+ # # the tokens passed will be an array of objects, what type of object is irrelevant,
13
+ # # just do what you need to do with them and return a single encrypted string.
14
+ # # for example, you will most likely join all of the objects into a single string and then encrypt that string
15
+ # end
16
+ #
17
+ # def self.matches?(crypted, *tokens)
18
+ # # return true if the crypted string matches the tokens.
19
+ # # depending on your algorithm you might decrypt the string then compare it to the token, or you might
20
+ # # encrypt the tokens and make sure it matches the crypted string, its up to you
21
+ # end
22
+ # end
23
+ module CryptoProviders
24
+ # = Sha512
25
+ #
26
+ # Uses the Sha512 hash algorithm to encrypt passwords.
27
+ class SHA512
28
+ include Common
29
+ class << self
30
+ def secure_digest(digest)
31
+ Digest::SHA512.hexdigest(digest)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end