lib/encrypted_strings/extensions/string.rb in encrypted_strings-0.0.1 vs lib/encrypted_strings/extensions/string.rb in encrypted_strings-0.0.2
- old
+ new
@@ -1,71 +1,144 @@
require 'openssl'
require 'base64'
module PluginAWeek #:nodoc:
- module EncryptedStrings #:nodoc:
+ module EncryptedStrings
module Extensions #:nodoc:
- # Adds encryption/decryption/equality methods
+ # Adds support for encryption/decryption of strings
module String
def self.included(base) #:nodoc:
base.class_eval do
attr_accessor :encryptor
alias_method :equals_without_encryption, :==
alias_method :==, :equals_with_encryption
end
end
- # Encrypts this string and replaces it with the encrypted value
- def encrypt!(*args)
- encrypted_string = encrypt(*args)
- self.encryptor = encrypted_string.encryptor
-
- replace(encrypted_string)
- end
-
- # Encrypts the current string using the encryption algorithm specified.
+ # Encrypts the current string using the specified encryption mode.
# The default encryption mode is sha.
#
- # Configuration options are encryption-specified. See the encryptor
- # class for that string to find out the options available.
+ # Configuration options are encryption-specific. See the encryptor
+ # class for that mode to find out the options available.
+ #
+ # == Example
+ #
+ # The following uses SHA mode to encrypt the string:
+ #
+ # password = "shhhh"
+ # password.encrypt # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
+ #
+ # == Custom encryption mode
+ #
+ # The following uses Symmetric mode (with a default key) to encrypt the
+ # string:
+ #
+ # PluginAWeek::EncryptedStrings::SymmetricEncryptor.default_key = "my_key"
+ # password = "shhhh"
+ # password.encrypt(:symmetric) # => "jDACXI5hMPI=\n"
+ #
+ # == Custom encryption options
+ #
+ # Some encryption modes also support additional configuration options
+ # that determine how to encrypt the string. For example, SHA supports
+ # a salt which seeds the algorithm:
+ #
+ # password = "shhhh"
+ # password.encrypt(:sha, :salt => "secret") # => "3b22cbe4acde873c3efc82681096f3ae69aff828"
def encrypt(*args)
encryptor = encryptor_from_args(*args)
encrypted_string = encryptor.encrypt(self)
encrypted_string.encryptor = encryptor
encrypted_string
end
- # Is this string encrypted?
+ # Encrypts this string and replaces it with the encrypted value. This
+ # takes the same parameters as #encrypt, but returns the same string
+ # instead of a different one.
+ #
+ # For example,
+ #
+ # password = "shhhh"
+ # password.encrypt!(:symmetric, :key => "my_key") # => "jDACXI5hMPI=\n"
+ # password # => "jDACXI5hMPI=\n"
+ def encrypt!(*args)
+ encrypted_string = encrypt(*args)
+ self.encryptor = encrypted_string.encryptor
+
+ replace(encrypted_string)
+ end
+
+ # Is this string encrypted? This will return true if the string is the
+ # result of a call to #encrypt or #encrypt! was previously invoked.
+ #
+ # For example,
+ #
+ # password = "shhhh"
+ # password.encrypted? # => false
+ # password.encrypt! # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
+ # password.encrypted? # => true
def encrypted?
!@encryptor.nil?
end
- # Decrypts this string and replaces it with the decrypted value
- def decrypt!(*args)
- replace(decrypt(*args))
- end
-
# Decrypts this string. If this is not a string that was previously encrypted,
# the encryption algorithm must be specified in the same way the
# algorithm is specified when encrypting a string.
def decrypt(*args)
raise ArgumentError, "An encrypt algorithm must be specified since we can't figure it out" if args.empty? && !@encryptor
- encryptor = @encryptor || encryptor_from_args(*args)
- encryptor.decrypt(self)
+ encryptor = args.any? ? encryptor_from_args(*args) : (@encryptor || encryptor_from_args(*args))
+ encrypted_string = encryptor.decrypt(self)
+ encrypted_string.encryptor = nil
+
+ encrypted_string
end
- # Can this string be decrypted?
+ # Decrypts this string and replaces it with the decrypted value This
+ # takes the same parameters as #decrypt, but returns the same string
+ # instead of a different one.
+ #
+ # For example,
+ #
+ # password = "jDACXI5hMPI=\n"
+ # password.decrypt!(:symmetric, :key => "my_key") # => "shhhh"
+ # password # => "shhhh"
+ def decrypt!(*args)
+ replace(decrypt(*args))
+ end
+
+ # Can this string be decrypted? Strings can only be decrypted if they
+ # have previously been decrypted +and+ the encryption algorithm supports
+ # decryption. To determine whether or not the encryption algorithm
+ # supports decryption, see the api for the algorithm's encryptor class.
def can_decrypt?
- !@encryptor.nil? && @encryptor.can_decrypt?
+ encrypted? && @encryptor.can_decrypt?
end
# Tests whether the other object is equal to this one. Encrypted strings
# will be tested not only on their encrypted strings, but also by
- # decrypting them and running tests against the decrypted value
+ # decrypting them and running tests against the decrypted value.
+ #
+ # == Equality with strings
+ #
+ # password = "shhhh"
+ # password.encrypt! # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
+ # password # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
+ # password == "shhhh" # => true
+ #
+ # == Equality with encrypted strings
+ #
+ # password = "shhhh"
+ # password.encrypt! # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
+ # password # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
+ # password == "shhhh" # => true
+ #
+ # another_password = "shhhh"
+ # another_password.encrypt! # => "66c85d26dadde7e1db27e15a0776c921e27143bd"
+ # password == another_password # => true
def equals_with_encryption(other)
if !(is_equal = equals_without_encryption(other)) && String === other
if encrypted?
if other.encrypted?
is_string_equal?(self, other) || is_string_equal?(other, self) || self.can_decrypt? && is_string_equal?(self.decrypt, other) || other.can_decrypt? && is_string_equal?(other.decrypt, self)
@@ -103,6 +176,6 @@
end
end
::String.class_eval do
include PluginAWeek::EncryptedStrings::Extensions::String
-end
\ No newline at end of file
+end