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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +104 -0
- data/lib/microsoft_graph_mailer/client.rb +51 -0
- data/lib/microsoft_graph_mailer/delivery.rb +49 -0
- data/lib/microsoft_graph_mailer/railtie.rb +11 -0
- data/lib/microsoft_graph_mailer/version.rb +5 -0
- data/lib/microsoft_graph_mailer.rb +16 -0
- metadata +143 -0
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,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: []
|