enmail 0.1.0 → 0.2.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.
data/README.md DELETED
@@ -1,115 +0,0 @@
1
- # EnMail
2
-
3
- [![Build
4
- Status](https://travis-ci.org/riboseinc/enmail.svg?branch=master)](https://travis-ci.org/riboseinc/enmail)
5
-
6
- EnMail (Encrypted mail) helps the Ruby mail gem send secure encrypted messages.
7
-
8
- The two ways for secure mail are:
9
- * OpenPGP
10
- * S/MIME
11
-
12
- This gem allows you to select different OpenPGP implementations
13
- including NetPGP and GnuPG as different OpenPGP adapters, and also
14
- S/MIME.
15
-
16
- ## Installation
17
-
18
- Add this line to your application's Gemfile:
19
-
20
- ```ruby
21
- gem "enmail"
22
- ```
23
-
24
- And then execute:
25
-
26
- ```sh
27
- bundle install
28
- ```
29
-
30
- Or install it yourself as:
31
-
32
- ```sh
33
- gem install enmail
34
- ```
35
-
36
- ## Configure
37
-
38
- The `EnMail` gem provides a very easier interface to set custom configurations
39
- or configure the underlying dependencies, we can configure it by adding an
40
- initializer with the following code
41
-
42
- ```ruby
43
- EnMail.configure do |config|
44
- config.sign_message = true
45
- config.smime_adapter = :openssl
46
- config.secret_key = "Secret Key String"
47
-
48
- config.certificates_path = "CERTIFICATES_ROOT_PAH"
49
- end
50
- ```
51
-
52
- Or
53
-
54
- ```ruby
55
- EnMail.configuration.certificates_path = "CERTIFICATES_ROOT_PAH"
56
- ```
57
-
58
- ## Usage
59
-
60
- ```sh
61
- bin/console
62
- ```
63
-
64
- ## Development
65
-
66
- We are following Sandi Metz's Rules for this gem, you can read the
67
- [description of the rules here][sandimetz]. All new code should follow these
68
- rules. If you make changes in a pre-existing file that violates these rules you
69
- should fix the violations as part of your contribution.
70
-
71
- ### Setup
72
-
73
- Clone the repository.
74
-
75
- ```sh
76
- git clone https://github.com/riboseinc/enmail
77
- ```
78
-
79
- Setup your environment.
80
-
81
- ```sh
82
- bin/setup
83
- ```
84
-
85
- Run the test suite
86
-
87
- ```sh
88
- bin/rspec
89
- ```
90
-
91
- ## Contributing
92
-
93
- First, thank you for contributing! We love pull requests from everyone. By
94
- participating in this project, you hereby grant [Ribose Inc.][ribose] the
95
- right to grant or transfer an unlimited number of non exclusive licenses or
96
- sub-licenses to third parties, under the copyright covering the contribution
97
- to use the contribution by all means.
98
-
99
- Here are a few technical guidelines to follow:
100
-
101
- 1. Open an [issue][issues] to discuss a new feature.
102
- 1. Write tests to support your new feature.
103
- 1. Make sure the entire test suite passes locally and on CI.
104
- 1. Open a Pull Request.
105
- 1. [Squash your commits][squash] after receiving feedback.
106
- 1. Party!
107
-
108
- ## Credits
109
-
110
- This gem is developed, maintained and funded by [Ribose Inc.][ribose]
111
-
112
- [ribose]: https://www.ribose.com
113
- [issues]: https://github.com/abunashir/enmail/issues
114
- [squash]: https://github.com/thoughtbot/guides/tree/master/protocol/git#write-a-feature
115
- [sandimetz]: http://robots.thoughtbot.com/post/50655960596/sandi-metz-rules-for-developers
@@ -1,75 +0,0 @@
1
- require "openssl"
2
-
3
- module EnMail
4
- class CertificateFinder
5
- def initialize(email:)
6
- @email = email
7
- end
8
-
9
- # Certificate
10
- #
11
- # This returns an `OpenSSL::X509::Certificate` instnace which
12
- # usages the content for the pem certificate. The certificate
13
- # name is the dotify version of the email with `pem` ext.
14
- #
15
- def certificate
16
- certificate_instance
17
- end
18
-
19
- # Private Key
20
- #
21
- # This returns an `OpenSSL::PKey::RSA` instnace which usages
22
- # the content for keyfile. The keyfile is the dotify version
23
- # of the email with `key` ext.
24
- #
25
- def private_key
26
- private_key_instance
27
- end
28
-
29
- # Self.find_by_email
30
- #
31
- # Initialize a new instnace with more readble interface.
32
- #
33
- def self.find_by_email(email)
34
- new(email: email)
35
- end
36
-
37
- private
38
-
39
- attr_reader :email
40
-
41
- def certificate_instance
42
- OpenSSL::X509::Certificate.new(
43
- certificate_file(extension: :pem),
44
- )
45
- end
46
-
47
- def private_key_instance
48
- OpenSSL::PKey::RSA.new(
49
- certificate_file(extension: :key),
50
- )
51
- end
52
-
53
- def certificate_file(extension:)
54
- content_for(
55
- [dotify_email, extension.to_s].join("."),
56
- )
57
- end
58
-
59
- def dotify_email
60
- @dotify_email ||= email.sub("@", ".")
61
- end
62
-
63
- def content_for(filename)
64
- File.read(certificate_file_with_path(filename))
65
- end
66
-
67
- def certificate_file_with_path(certificate)
68
- File.join(certificates_root, certificate)
69
- end
70
-
71
- def certificates_root
72
- EnMail.configuration.certificates_path
73
- end
74
- end
75
- end
@@ -1,21 +0,0 @@
1
- require "enmail/configuration"
2
-
3
- module EnMail
4
- module Config
5
- def configure
6
- if block_given?
7
- yield configuration
8
- end
9
- end
10
-
11
- def configuration
12
- @configuration ||= EnMail::Configuration.new
13
- end
14
- end
15
-
16
- # Expose config module methods as class level method, so we can
17
- # use those method whenever necessary. Specially `configuration`
18
- # throughout the gem
19
- #
20
- extend Config
21
- end
@@ -1,80 +0,0 @@
1
- module EnMail
2
- class Configuration
3
- attr_reader :smime_adapter
4
- attr_accessor :sign_message, :certificates_path
5
- attr_accessor :sign_key, :encrypt_key
6
-
7
- def initialize
8
- @sign_message = true
9
- @smime_adapter = :openssl
10
- end
11
-
12
- # Signable?
13
- #
14
- # Returns the message signing status, by defualt it will return `true`.
15
- # If the user provided a custom configuration for `sign_message` then
16
- # it will use that status, so we can easily skip it when desirable.
17
- #
18
- def signable?
19
- sign_message == true
20
- end
21
-
22
- # Set smime adapter
23
- #
24
- # This allows us to set a valid smime adapter, once this has been
25
- # set then the gem will use this on to select the correct adapter
26
- # class and then use that one to to `sign` a message.
27
- #
28
- # @param adapter adapter you want to use to sign the message
29
- #
30
- def smime_adapter=(adapter)
31
- if valid_smime_adapter?(adapter)
32
- @smime_adapter = adapter
33
- end
34
- end
35
-
36
- # Adapter klass name
37
- #
38
- # This returns the string class name for the configured smime
39
- # adapter. We are lazely loading the adapter so this interface
40
- # will return the string verion. Please do not forget to use
41
- # `Object.const_get` before invokng any method on it.
42
- #
43
- def smime_adapter_klass
44
- smime_adapter_symbol_to_klass
45
- end
46
-
47
- # Default key
48
- #
49
- # This returns a Key instance with the configured keys.
50
- # @return [EnMail::Key] the configured default key attributes.
51
- #
52
- def defualt_key
53
- EnMail::Key.new(sign_key: sign_key, encrypt_key: encrypt_key)
54
- end
55
-
56
- private
57
-
58
- def valid_smime_adapter?(adapter)
59
- smime_adapters.include?(adapter.to_sym)
60
- end
61
-
62
- def smime_adapter_symbol_to_klass
63
- adapter_klasses.fetch(smime_adapter.to_sym)
64
- end
65
-
66
- # Supported smime adapters
67
- #
68
- # The list of the supported smime adapters, if we add support for
69
- # a new smime adapter then please update this list and this way we
70
- # can ensure user can configure the gem with supported adapter only
71
- #
72
- def smime_adapters
73
- [:openssl].freeze
74
- end
75
-
76
- def adapter_klasses
77
- { openssl: "EnMail::Adapters::OpenSSL" }
78
- end
79
- end
80
- end
@@ -1,43 +0,0 @@
1
- module EnMail
2
- module EnMailable
3
- # Sign a message
4
- #
5
- # This interface allow us to sign a message while using this gem, this
6
- # also forecefully sets the `signable` status true, so it ensures that
7
- # the specific message will be signed before sending out.
8
- #
9
- # @param passphrase [String] the passphrase for the sign key
10
- # @param key [EnMail::Key] the key model instance
11
- #
12
- def sign(passphrase: "", key: nil)
13
- @key = key
14
-
15
- unless passphrase.empty?
16
- signing_key.passphrase = passphrase
17
- end
18
- end
19
-
20
- # Signing key
21
- #
22
- # This returns the signing key when applicable, the default signing
23
- # key is configured through an initializer, but we are also allowing
24
- # user to provide a custom key when they are invoking an interface.
25
- #
26
- # @return [EnMail::Key] the key model instance
27
- #
28
- def signing_key
29
- @key || EnMail.configuration.defualt_key
30
- end
31
-
32
- # Signing status
33
- #
34
- # This returns the message signing status based on the user specified
35
- # configuration and signing key. If the user enabled sign_message and
36
- # provided a valid signing key then this will return true otherwise
37
- # false, this can be used before trying to sing a message.
38
- #
39
- def signable?
40
- signing_key.sign_key && EnMail.configuration.signable?
41
- end
42
- end
43
- end
@@ -1,53 +0,0 @@
1
- module EnMail
2
- class Key
3
- # @!attribute [r] sign_key
4
- # @return [String] the signing key content
5
- #
6
- attr_reader :sign_key
7
-
8
- # @!attribute passphrase
9
- # @return [String] the signing key passphrase
10
- #
11
- attr_reader :passphrase
12
-
13
- # @!attribute [r] encrypt_key
14
- # @return [String] the encryping key content
15
- #
16
- attr_reader :encrypt_key
17
-
18
- # @!attribute [r] certificate
19
- # @return [String] the certificate content
20
- #
21
- attr_reader :certificate
22
-
23
- # Initialize a key model with the basic attributes, this expects us
24
- # to provided the key/certificate as string and when we actually use
25
- # it then the configured adapter will use it as necessary.
26
- #
27
- # @param :sign_key [String] the signing key content
28
- # @param :passphrase [String] the passphrase for encrypted key
29
- # @param :encrypt_key [String] the encryping key content
30
- # @param :certificate [String] the signing certificate content
31
- #
32
- # @return [EnMail::Key] - the EnMail::Key model
33
- #
34
- def initialize(attributes)
35
- @sign_key = attributes.fetch(:sign_key, "")
36
- @passphrase = attributes.fetch(:passphrase, "")
37
- @encrypt_key = attributes.fetch(:encrypt_key, "")
38
- @certificate = attributes.fetch(:certificate, "")
39
- end
40
-
41
- # Set the passphrase value
42
- #
43
- # This allow us to set the passphrase after initialization, so if the
44
- # user prefere then they can pass the passphrase during the siging /
45
- # encrypting steps and we can set that one when necessary
46
- #
47
- # @param passphrase [String] the passphrase for encrypted key
48
- #
49
- def passphrase=(passphrase)
50
- @passphrase = passphrase
51
- end
52
- end
53
- end
@@ -1,18 +0,0 @@
1
- require "mail"
2
- require "enmail/enmailable"
3
-
4
- module Mail
5
- class Message
6
- # Include enmail interfaces
7
- #
8
- # We are supporting some custom interfaces for the mail instance,
9
- # so the user can use `sign`, `encrypt` and `decrypt` directly to
10
- # their mail instance.
11
- #
12
- # The `EnMail::EnMailable` module defines all of the interfaces
13
- # to support the above funcitonality, so let's include that and
14
- # please check `EnMail::EnMailable` for more details on those.
15
- #
16
- include EnMail::EnMailable
17
- end
18
- end
@@ -1,53 +0,0 @@
1
- module MailInterceptors
2
- class PGP
3
-
4
- def self.delivering_email(mail)
5
-
6
- return unless mail.gpg
7
-
8
- options = TrueClass === mail.gpg ? { encrypt: true } : mail.gpg
9
- # encrypt and sign are off -> do not encrypt or sign
10
- if options.delete(:encrypt)
11
- receivers = []
12
- receivers += mail.to if mail.to
13
- receivers += mail.cc if mail.cc
14
- receivers += mail.bcc if mail.bcc
15
-
16
- if options[:sign_as]
17
- options[:sign] = true
18
- options[:signers] = options.delete(:sign_as)
19
- elsif options[:sign]
20
- options[:signers] = mail.from
21
- end
22
-
23
- # Need to remove any non-SignedPart & non-SignPart
24
- mail.body = ''
25
-
26
- mail.add_part Mail::Gpg::VersionPart.new
27
- mail.add_part Mail::Gpg::EncryptedPart.new(mail, options.merge({recipients: receivers}))
28
- mail.content_type "multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=#{mail.boundary}"
29
- mail.body.preamble = options[:preamble] || "This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156)"
30
-
31
- elsif options[:sign] || options[:sign_as]
32
-
33
- to_be_signed = Mail::Gpg::SignedPart.build(mail)
34
-
35
- # Need to remove any non-SignedPart & non-SignPart
36
- mail.body = ''
37
-
38
- mail.add_part to_be_signed
39
- mail.add_part to_be_signed.sign(options)
40
-
41
- mail.content_type "multipart/signed; micalg=pgp-sha1; protocol=\"application/pgp-signature\"; boundary=#{mail.boundary}"
42
- mail.body.preamble = options[:preamble] || "This is an OpenPGP/MIME signed message (RFC 4880 and 3156)"
43
- end
44
-
45
- puts "pee pee mail@"
46
- pp mail
47
-
48
- rescue Exception
49
- raise $! if mail.raise_encryption_errors
50
- end
51
-
52
- end
53
- end