diff --git a/lib/net/smtp/auth_xoauth2.rb b/lib/net/smtp/auth_xoauth2.rb new file mode 100644 index 0000000..ece2e11 --- /dev/null +++ b/lib/net/smtp/auth_xoauth2.rb @@ -0,0 +1,17 @@ +class Net::SMTP + class AuthXoauth2 < Net::SMTP::Authenticator + auth_type :xoauth2 + + def auth(user, secret) + token = xoauth2_string(user, secret) + + finish("AUTH XOAUTH2 #{base64_encode(token)}") + end + + private + + def xoauth2_string(user, secret) + "user=#{user}\1auth=Bearer #{secret}\1\1" + end + end +end diff --git a/test/net/smtp/test_smtp.rb b/test/net/smtp/test_smtp.rb index 85bc1bc..02f78dc 100644 --- a/test/net/smtp/test_smtp.rb +++ b/test/net/smtp/test_smtp.rb @@ -147,6 +147,21 @@ def server.auth(*) assert_equal "235", err.response.status end + def test_auth_xoauth2 + server = FakeServer.start(auth: 'xoauth2') + smtp = Net::SMTP.start 'localhost', server.port + assert smtp.authenticate("account", "token", :xoauth2).success? + assert_equal "AUTH XOAUTH2 dXNlcj1hY2NvdW50AWF1dGg9QmVhcmVyIHRva2VuAQE=\r\n", server.commands.last + end + + def test_unsucessful_auth_xoauth2 + server = FakeServer.start(auth: 'xoauth2') + smtp = Net::SMTP.start 'localhost', server.port + err = assert_raise(Net::SMTPAuthenticationError) { smtp.authenticate("account", "password", :xoauth2) } + assert_equal "535 5.7.8 Error: authentication failed: authentication failure\n", err.message + assert_equal "535", err.response.status + end + def test_send_message port = fake_server_start smtp = Net::SMTP.start 'localhost', port @@ -712,6 +727,8 @@ def auth(*args) @sock.puts "334 PDEyMzQ1Njc4OTAuMTIzNDVAc2VydmVybmFtZT4=\r\n" r = @sock.gets&.chomp r == 'YWNjb3VudCAyYzBjMTgxZjkxOGU2ZGM5Mjg3Zjk3N2E1ODhiMzg1YQ==' + when 'XOAUTH2' + arg == 'dXNlcj1hY2NvdW50AWF1dGg9QmVhcmVyIHRva2VuAQE=' end if result @sock.puts "235 2.7.0 Authentication successful\r\n"