مراية لـ
https://github.com/postalserver/postal.git
تم المزامنة 2026-01-20 22:59:48 +00:00
refactor: move lib/postal/smtp_server to app/lib/smtp_server
هذا الالتزام موجود في:
120
spec/lib/smtp_server/client/auth_spec.rb
Normal file
120
spec/lib/smtp_server/client/auth_spec.rb
Normal file
@@ -0,0 +1,120 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
module SMTPServer
|
||||
|
||||
describe Client do
|
||||
let(:ip_address) { "1.2.3.4" }
|
||||
subject(:client) { described_class.new(ip_address) }
|
||||
|
||||
before do
|
||||
client.handle("HELO test.example.com")
|
||||
end
|
||||
|
||||
describe "AUTH PLAIN" do
|
||||
context "when no credentials are provided on the initial data" do
|
||||
it "returns a 334" do
|
||||
expect(client.handle("AUTH PLAIN")).to eq("334")
|
||||
end
|
||||
|
||||
it "accepts the username and password from the next input" do
|
||||
client.handle("AUTH PLAIN")
|
||||
credential = create(:credential, type: "SMTP")
|
||||
expect(client.handle(credential.to_smtp_plain)).to match(/235 Granted for/)
|
||||
end
|
||||
end
|
||||
|
||||
context "when valid credentials are provided on one line" do
|
||||
it "authenticates and returns a response" do
|
||||
credential = create(:credential, type: "SMTP")
|
||||
expect(client.handle("AUTH PLAIN #{credential.to_smtp_plain}")).to match(/235 Granted for/)
|
||||
expect(client.credential).to eq credential
|
||||
end
|
||||
end
|
||||
|
||||
context "when invalid credentials are provided" do
|
||||
it "returns an error and resets the state" do
|
||||
base64 = Base64.encode64("user\0pass")
|
||||
expect(client.handle("AUTH PLAIN #{base64}")).to eq("535 Invalid credential")
|
||||
expect(client.state).to eq :welcomed
|
||||
end
|
||||
end
|
||||
|
||||
context "when username or password is missing" do
|
||||
it "returns an error and resets the state" do
|
||||
base64 = Base64.encode64("pass")
|
||||
expect(client.handle("AUTH PLAIN #{base64}")).to eq("535 Authenticated failed - protocol error")
|
||||
expect(client.state).to eq :welcomed
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "AUTH LOGIN" do
|
||||
context "when no username is provided on the first line" do
|
||||
it "requests the username" do
|
||||
expect(client.handle("AUTH LOGIN")).to eq("334 VXNlcm5hbWU6")
|
||||
end
|
||||
end
|
||||
|
||||
context "when a username is provided on the first line" do
|
||||
it "requests a password" do
|
||||
username = Base64.encode64("xx")
|
||||
expect(client.handle("AUTH LOGIN #{username}")).to eq("334 UGFzc3dvcmQ6")
|
||||
end
|
||||
|
||||
it "authenticates and returns a response" do
|
||||
credential = create(:credential, type: "SMTP")
|
||||
username = Base64.encode64("xx")
|
||||
password = Base64.encode64(credential.key)
|
||||
expect(client.handle("AUTH LOGIN #{username}")).to eq("334 UGFzc3dvcmQ6")
|
||||
expect(client.handle(password)).to match(/235 Granted for/)
|
||||
expect(client.credential).to eq credential
|
||||
end
|
||||
end
|
||||
|
||||
context "when invalid credentials are provided" do
|
||||
it "returns an error and resets the state" do
|
||||
username = Base64.encode64("xx")
|
||||
password = Base64.encode64("xx")
|
||||
expect(client.handle("AUTH LOGIN #{username}")).to eq("334 UGFzc3dvcmQ6")
|
||||
expect(client.handle(password)).to eq("535 Invalid credential")
|
||||
expect(client.state).to eq :welcomed
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "AUTH CRAM-MD5" do
|
||||
context "when valid credentials are provided" do
|
||||
it "authenticates and returns a response" do
|
||||
credential = create(:credential, type: "SMTP")
|
||||
result = client.handle("AUTH CRAM-MD5")
|
||||
expect(result).to match(/\A334 [A-Za-z0-9=]+\z/)
|
||||
challenge = Base64.decode64(result.split[1])
|
||||
password = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("md5"), credential.key, challenge)
|
||||
base64 = Base64.encode64("#{credential.server.organization.permalink}/#{credential.server.permalink} #{password}")
|
||||
expect(client.handle(base64)).to match(/235 Granted for/)
|
||||
expect(client.credential).to eq credential
|
||||
end
|
||||
end
|
||||
|
||||
context "when no org/server matches the provided username" do
|
||||
it "returns an error" do
|
||||
client.handle("AUTH CRAM-MD5")
|
||||
base64 = Base64.encode64("org/server password")
|
||||
expect(client.handle(base64)).to eq "535 Denied"
|
||||
end
|
||||
end
|
||||
|
||||
context "when invalid credentials are provided" do
|
||||
it "returns an error and resets the state" do
|
||||
server = create(:server)
|
||||
base64 = Base64.encode64("#{server.organization.permalink}/#{server.permalink} invalid-password")
|
||||
client.handle("AUTH CRAM-MD5")
|
||||
expect(client.handle(base64)).to eq("535 Denied")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
المرجع في مشكلة جديدة
حظر مستخدم