microsoft_graph_mailer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 12632ade885e197f206aa7cbdaa9be6770820b9a47de70eeaf092f606928c911
4
+ data.tar.gz: 409fee6a54f49282b55cb8384a3d4e279e747de350fae421438b19fd43624a28
5
+ SHA512:
6
+ metadata.gz: 156c69eebea594d1aa1a554155cc4fb82aeeca74085fe8bd87f90e66f01a88a041ce0044a3ddbcff05cd4175394b825bc51a2a97d9910454a4e6b122e5b07761
7
+ data.tar.gz: 2ed8b199e9f26d0629f78a153c857fe13b1645a99515c3f21c3db9527503f293b933d47429d01e0df277a82a2f0da6ba469ee1720999e674dc14ccba8a1693fa
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 GitLab B.V.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # microsoft_graph_mailer
2
+
3
+ This gem allows delivery of emails using [Microsoft Graph API](https://docs.microsoft.com/en-us/graph/api/user-sendmail) with [OAuth 2.0 client credentials flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow).
4
+
5
+ ## The reason for this gem
6
+
7
+ See [https://gitlab.com/groups/gitlab-org/-/epics/8259](https://gitlab.com/groups/gitlab-org/-/epics/8259).
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'microsoft_graph_mailer'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ ```shell
20
+ bundle
21
+ ```
22
+
23
+ Or install it yourself as:
24
+
25
+ ```shell
26
+ gem install microsoft_graph_mailer
27
+ ```
28
+
29
+ ## Settings
30
+
31
+ To use the Microsoft Graph API to send mails, you will
32
+ need to create an application in the Azure Active Directory. See the
33
+ [Microsoft instructions](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) for more details:
34
+
35
+ 1. Sign in to the [Azure portal](https://portal.azure.com).
36
+ 1. Search for and select `Azure Active Directory`.
37
+ 1. Under `Manage`, select `App registrations` > `New registration`.
38
+ 1. Enter a `Name` for your application, such as `MicrosoftGraphMailer`. Users of your app might see this name, and you can change it later.
39
+ 1. If `Supported account types` is listed, select the appropriate option.
40
+ 1. Leave `Redirect URI` blank. This is not needed.
41
+ 1. Select `Register`.
42
+ 1. Under `Manage`, select `Certificates & secrets`.
43
+ 1. Under `Client secrets`, select `New client secret`, and enter a name.
44
+ 1. Under `Expires`, select `Never`, unless you plan on updating the credentials every time it expires.
45
+ 1. Select `Add`. Record the secret value in a safe location for use in a later step.
46
+ 1. Under `Manage`, select `API Permissions` > `Add a permission`. Select `Microsoft Graph`.
47
+ 1. Select `Application permissions`.
48
+ 1. Under the `Mail` node, select `Mail.Send`. Then select Add permissions.
49
+ 1. If `User.Read` is listed in the permission list, you can delete this.
50
+ 1. Click `Grant admin consent` for these permissions.
51
+
52
+ - `user_id` - The unique identifier for the user. To use Microsoft Graph on behalf of the user.
53
+ - `tenant` - The directory tenant the application plans to operate against, in GUID or domain-name format.
54
+ - `client_id` - The application ID that's assigned to your app. You can find this information in the portal where you registered your app.
55
+ - `client_secret` - The client secret that you generated for your app in the app registration portal.
56
+
57
+ ## Usage
58
+
59
+ ```ruby
60
+ require "microsoft_graph_mailer"
61
+
62
+ microsoft_graph_mailer = MicrosoftGraphMailer::Delivery.new(
63
+ {
64
+ user_id: "YOUR-USER-ID",
65
+ tenant: "YOUR-TENANT-ID",
66
+ client_id: "YOUR-CLIENT-ID",
67
+ client_secret: "YOUR-CLIENT-SECRET-ID"
68
+ # Defaults to "https://login.microsoftonline.com".
69
+ azure_ad_endpoint: "https://login.microsoftonline.us",
70
+ # Defaults to "https://graph.microsoft.com".
71
+ graph_endpoint: "https://graph.microsoft.us"
72
+ }
73
+ )
74
+
75
+ message = Mail.new do
76
+ from "about@gitlab.com"
77
+ to "to@example.com"
78
+ subject "GitLab Mission"
79
+
80
+ html_part do
81
+ content_type "text/html; charset=UTF-8"
82
+ body "It is GitLab's mission to make it so that <strong>everyone can contribute</strong>."
83
+ end
84
+ end
85
+
86
+ microsoft_graph_mailer.deliver!(message)
87
+ ```
88
+
89
+ ## Usage with ActionMailer
90
+
91
+ ```ruby
92
+ ActionMailer::Base.delivery_method = :microsoft_graph
93
+
94
+ ActionMailer::Base.microsoft_graph_settings = {
95
+ user_id: "YOUR-USER-ID",
96
+ tenant: "YOUR-TENANT-ID",
97
+ client_id: "YOUR-CLIENT-ID",
98
+ client_secret: "YOUR-CLIENT-SECRET-ID"
99
+ # Defaults to "https://login.microsoftonline.com".
100
+ azure_ad_endpoint: "https://login.microsoftonline.us",
101
+ # Defaults to "https://graph.microsoft.com".
102
+ graph_endpoint: "https://graph.microsoft.us"
103
+ }
104
+ ```
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "oauth2"
4
+
5
+ module MicrosoftGraphMailer
6
+ class Client
7
+ attr_accessor :user_id, :tenant, :client_id, :client_secret, :azure_ad_endpoint, :graph_endpoint
8
+
9
+ def initialize(user_id:, tenant:, client_id:, client_secret:, azure_ad_endpoint:, graph_endpoint:)
10
+ @user_id = user_id
11
+ @tenant = tenant
12
+ @client_id = client_id
13
+ @client_secret = client_secret
14
+ @azure_ad_endpoint = azure_ad_endpoint
15
+ @graph_endpoint = graph_endpoint
16
+ end
17
+
18
+ def send_mail(message_in_mime_format)
19
+ # https://docs.microsoft.com/en-us/graph/api/user-sendmail
20
+ token.post(
21
+ send_mail_url,
22
+ headers: { "Content-type" => "text/plain" },
23
+ body: Base64.encode64(message_in_mime_format)
24
+ )
25
+ end
26
+
27
+ private
28
+
29
+ def token
30
+ # https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
31
+ OAuth2::Client.new(
32
+ client_id,
33
+ client_secret,
34
+ site: azure_ad_endpoint,
35
+ token_url: "/#{tenant}/oauth2/v2.0/token"
36
+ ).client_credentials.get_token({ scope: scope })
37
+ end
38
+
39
+ def scope
40
+ "#{graph_endpoint}/.default"
41
+ end
42
+
43
+ def base_url
44
+ "#{graph_endpoint}/v1.0/users/#{user_id}"
45
+ end
46
+
47
+ def send_mail_url
48
+ "#{base_url}/sendMail"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "client"
4
+
5
+ module MicrosoftGraphMailer
6
+ class Delivery
7
+ attr_reader :microsoft_graph_settings
8
+
9
+ def initialize(microsoft_graph_settings)
10
+ @microsoft_graph_settings = microsoft_graph_settings
11
+
12
+ [:user_id, :tenant, :client_id, :client_secret].each do |setting|
13
+ unless microsoft_graph_settings[setting]
14
+ raise MicrosoftGraphMailer::ConfigurationError, "'#{setting}' is missing"
15
+ end
16
+ end
17
+
18
+ @microsoft_graph_settings[:azure_ad_endpoint] ||= "https://login.microsoftonline.com"
19
+ @microsoft_graph_settings[:graph_endpoint] ||= "https://graph.microsoft.com"
20
+ end
21
+
22
+ def deliver!(message)
23
+ # https://github.com/mikel/mail/pull/872
24
+ if message[:bcc]
25
+ previous_message_bcc_include_in_headers = message[:bcc].include_in_headers
26
+ message[:bcc].include_in_headers = true
27
+ end
28
+
29
+ message_in_mime_format = message.encoded
30
+
31
+ client = MicrosoftGraphMailer::Client.new(
32
+ user_id: microsoft_graph_settings[:user_id],
33
+ tenant: microsoft_graph_settings[:tenant],
34
+ client_id: microsoft_graph_settings[:client_id],
35
+ client_secret: microsoft_graph_settings[:client_secret],
36
+ azure_ad_endpoint: microsoft_graph_settings[:azure_ad_endpoint],
37
+ graph_endpoint: microsoft_graph_settings[:graph_endpoint]
38
+ )
39
+
40
+ response = client.send_mail(message_in_mime_format)
41
+
42
+ raise MicrosoftGraphMailer::DeliveryError unless response.status == 202
43
+
44
+ response
45
+ ensure
46
+ message[:bcc].include_in_headers = previous_message_bcc_include_in_headers if message[:bcc]
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "delivery"
4
+
5
+ module MicrosoftGraphMailer
6
+ class Railtie < Rails::Railtie
7
+ ActiveSupport.on_load(:action_mailer) do
8
+ add_delivery_method :microsoft_graph, MicrosoftGraphMailer::Delivery
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MicrosoftGraphMailer
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "microsoft_graph_mailer/delivery"
4
+ require_relative "microsoft_graph_mailer/railtie" if defined?(Rails::Railtie)
5
+ require_relative "microsoft_graph_mailer/version"
6
+
7
+ module MicrosoftGraphMailer
8
+ class Error < StandardError
9
+ end
10
+
11
+ class ConfigurationError < Error
12
+ end
13
+
14
+ class DeliveryError < Error
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: microsoft_graph_mailer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Bogdan Denkovych
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-09-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mail
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oauth2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.4.4
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '3'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.4.4
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: debug
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.0.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: rails
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 3.11.0
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 3.11.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: webmock
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 3.18.1
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 3.18.1
103
+ description:
104
+ email:
105
+ - bdenkovych@gitlab.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - LICENSE.txt
111
+ - README.md
112
+ - lib/microsoft_graph_mailer.rb
113
+ - lib/microsoft_graph_mailer/client.rb
114
+ - lib/microsoft_graph_mailer/delivery.rb
115
+ - lib/microsoft_graph_mailer/railtie.rb
116
+ - lib/microsoft_graph_mailer/version.rb
117
+ homepage: https://gitlab.com/gitlab-org/gitlab/-/tree/master/vendor/gems/microsoft_graph_mailer
118
+ licenses:
119
+ - MIT
120
+ metadata:
121
+ homepage_uri: https://gitlab.com/gitlab-org/gitlab/-/tree/master/vendor/gems/microsoft_graph_mailer
122
+ source_code_uri: https://gitlab.com/gitlab-org/gitlab/-/tree/master/vendor/gems/microsoft_graph_mailer
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 2.7.0
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubygems_version: 3.3.22
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Allows delivery of emails using Microsoft Graph API with OAuth 2.0 client
142
+ credentials flow
143
+ test_files: []