Compare commits
5 Commits
b05502fedf
...
99c1495d3f
Author | SHA1 | Date |
---|---|---|
Arthur POULET | 99c1495d3f | |
Arthur POULET | ea02fe40ca | |
Arthur POULET | f9a0648264 | |
Arthur POULET | 43accadaf3 | |
Arthur POULET | 87002a9571 |
|
@ -3,6 +3,8 @@
|
|||
$LOAD_PATH << File.join(Dir.pwd, "lib")
|
||||
|
||||
require "app"
|
||||
require "protocols"
|
||||
require "models"
|
||||
require "pry"
|
||||
|
||||
# mailinglist1 = Mailinglist.build(name: "FreeML", suffix: "free", strategy: "free").save
|
||||
|
|
|
@ -5,6 +5,8 @@ $LOAD_PATH << File.join(Dir.pwd, "lib")
|
|||
require "app"
|
||||
require "optparse"
|
||||
require "uuid"
|
||||
require "protocols"
|
||||
require "models"
|
||||
|
||||
options = {
|
||||
name: UUID.generate,
|
||||
|
@ -21,8 +23,17 @@ OptionParser.new do |opts|
|
|||
opts.on("-n=NAME", "--name=NAME", "Define the name of the option") do |v|
|
||||
options[:name] = v
|
||||
end
|
||||
|
||||
opts.on("-e=EMAIL", "--email=EMAIL", "Initialize the list with some emails, separated with ,") do |email|
|
||||
options[:emails] ||= []
|
||||
options[:emails] << email
|
||||
end
|
||||
end.parse!
|
||||
|
||||
options[:suffix] = options[:name].gsub(/[^a-zA-Z0-9]+/, '-')
|
||||
mailinglist = Mailinglist.build(name: options[:name], suffix: options[:suffix], strategy: options[:strategy]).save
|
||||
pp mailinglist
|
||||
|
||||
options[:emails].each do |email|
|
||||
pp Email.register!(name: email, email: email, mailinglist: mailinglist)
|
||||
end
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
$LOAD_PATH << File.join(Dir.pwd, "lib")
|
||||
|
||||
require "app"
|
||||
require "protocols"
|
||||
require "models"
|
||||
|
||||
mailinglist0 = Mailinglist.build(name: "AutoReg", suffix: "autoreg", strategy: "autoregister").save
|
||||
mailinglist1 = Mailinglist.build(name: "FreeML", suffix: "free", strategy: "free").save
|
||||
mailinglist2 = Mailinglist.build(name: "ValidatedML", suffix: "validated", strategy: "validated").save
|
||||
mailinglist3 = Mailinglist.build(name: "ClosedML", suffix: "closed", strategy: "closed").save
|
||||
pp mailinglist1, mailinglist2, mailinglist3
|
||||
|
||||
# email1 = Email.register!(name: "AP", email: "arthur.poulet.hunk@sceptique.eu", mailinglist: mailinglist)
|
||||
# email2 = Email.register!(name: "AP2", email: "arthur.poulet.hunk2@sceptique.eu", mailinglist: mailinglist)
|
||||
# pp email1, email2
|
||||
pp mailinglist0, mailinglist1, mailinglist2, mailinglist3
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
$LOAD_PATH << File.join(Dir.pwd, "lib")
|
||||
|
||||
require "app"
|
||||
require "protocols"
|
||||
require "models"
|
||||
require "distributor"
|
||||
|
||||
Signal.trap("SIGINT") do
|
||||
|
|
3
bin/http
3
bin/http
|
@ -2,7 +2,10 @@
|
|||
$LOAD_PATH << File.join(Dir.pwd, "lib")
|
||||
|
||||
require "app"
|
||||
require "protocols"
|
||||
require "models"
|
||||
require "sinatra"
|
||||
|
||||
set :views, File.expand_path(File.join(settings.root + "/../lib/web/views"))
|
||||
|
||||
require "web"
|
||||
|
|
|
@ -8,5 +8,3 @@ require "sequel"
|
|||
$db = Sequel.connect(ENV["DB_URL"])
|
||||
|
||||
require_relative "logger"
|
||||
require_relative "protocols"
|
||||
require_relative "models" rescue nil
|
||||
|
|
|
@ -36,12 +36,13 @@ class Distributor
|
|||
$logger.info "incoming email from #{mail.from} | #{mail.subject}"
|
||||
list = Mailinglist.search_mail(mail)
|
||||
if list
|
||||
# TODO: create list from mail ?
|
||||
subject, subject_attributes = mail.subject.split(",", 2)
|
||||
attributes = Attributes.parse(subject: subject_attributes, body: mail.body)
|
||||
handler = @handlers[subject] || @handlers[:default]
|
||||
$logger.info "#{handler.class}#handle on #{list.email} for #{mail.from}"
|
||||
handler.handle(list:, to: mail, attributes:)
|
||||
handler.handle(list: list, mail: mail, attributes: attributes)
|
||||
else
|
||||
$logger.warn "list #{mail.to} do not exist (asked by #{mail.from})"
|
||||
end
|
||||
mail.seen!(imap_client: @imap_client)
|
||||
end
|
||||
|
|
|
@ -4,31 +4,31 @@ class Distributor
|
|||
class SetPermissions < Action
|
||||
SET_PERMISSIONS_TEMPLATE = Actions.template("set_permissions.success")
|
||||
|
||||
def handle(list:, to:, attributes:)
|
||||
def handle(list:, mail:, attributes:)
|
||||
return if attributes["user-email"].nil? # drop missing param
|
||||
return if attributes["permissions"].nil? # drop missing param
|
||||
|
||||
modo = Email.first(mailinglist: list, email: to.from)
|
||||
modo = Email.first(mailinglist: list, email: mail.from)
|
||||
if !modo&.modo? && !modo&.op?
|
||||
$logger.warn "SECU <#{to.from}> failed to set-permissions <#{list.email}> modo"
|
||||
$logger.warn "SECU <#{mail.from}> failed to set-permissions <#{list.email}> modo"
|
||||
return nil
|
||||
end
|
||||
|
||||
user_email = attributes["user-email"]
|
||||
user = Email.first(mailinglist: list, email: user_email)
|
||||
if user.nil?
|
||||
$logger.warn "SECU <#{to.from}> failed to set-permissions on non-existing email <#{user_email}>"
|
||||
$logger.warn "SECU <#{mail.from}> failed to set-permissions on non-existing email <#{user_email}>"
|
||||
return nil
|
||||
end
|
||||
|
||||
if user.op? && !modo.op?
|
||||
$logger.warn "SECU <#{to.from}> failed to set-permissions on op email <#{user_email}>"
|
||||
$logger.warn "SECU <#{mail.from}> failed to set-permissions on op email <#{user_email}>"
|
||||
return nil
|
||||
end
|
||||
|
||||
permissions = attributes["permissions"].to_i
|
||||
if Email::Permissions.op?(permissions) && !modo.op?
|
||||
$logger.warn "SECU <#{to.from}> failed to set op permissions on email <#{user_email}>"
|
||||
$logger.warn "SECU <#{mail.from}> failed to set op permissions on email <#{user_email}>"
|
||||
return nil
|
||||
end
|
||||
|
||||
|
|
|
@ -7,81 +7,86 @@ class Distributor
|
|||
WAIT_USER_TEMPLATE = Actions.template("subscribe.wait_user")
|
||||
WAIT_MODO_TEMPLATE = Actions.template("subscribe.wait_modo")
|
||||
|
||||
def handle(list:, to:, attributes:)
|
||||
def handle(list:, mail:, attributes:)
|
||||
register =
|
||||
begin
|
||||
Email.register!(mailinglist: list, name: to.from_name, email: to.from).save
|
||||
Email.register!(mailinglist: list, name: mail.from_name, email: mail.from).save
|
||||
rescue StandardError => e
|
||||
$logger.error e.message
|
||||
nil
|
||||
end
|
||||
if register
|
||||
if !register.reader?
|
||||
handle_wait_validation(list:, to:, register:)
|
||||
handle_wait_validation(list: list, mail: mail, register: register)
|
||||
else
|
||||
handle_subscribed(list:, to:, register:)
|
||||
handle_subscribed(list: list, mail: mail, register: register)
|
||||
end
|
||||
else
|
||||
handle_403(list:, to:)
|
||||
handle_403(list: list, mail: mail)
|
||||
end
|
||||
end
|
||||
|
||||
def handle_wait_validation(list:, to:, register:)
|
||||
def handle_wait_validation(list:, mail:, register:)
|
||||
$logger.debug "Subscribe#handle_wait_validation on #{list.email} for #{to.from}"
|
||||
body = WAIT_USER_TEMPLATE.result binding
|
||||
@distributor.distribute(to.to_response(list:, to:, body:))
|
||||
@distributor.distribute(mail.to_response(list: list, mail: mail, body: body))
|
||||
|
||||
modo = list.enabled_modos.first
|
||||
body = WAIT_MODO_TEMPLATE.result binding
|
||||
@distributor.distribute(
|
||||
Protocols::Mail.build(
|
||||
subject: "ML #{list.name} requires validaton for #{to.from}", list:, to: modo.email, body:,
|
||||
subject: "ML #{list.name} requires validaton for #{mail.from}", list: list, to: modo.email, body: body,
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
def handle_subscribed(list:, to:, register:)
|
||||
$logger.debug "Subscribe#handle_subscribed on #{list.email} for #{to.from}"
|
||||
def handle_subscribed(list:, mail:, register:)
|
||||
$logger.debug "Subscribe#handle_subscribed on #{list.email} for #{mail.from}"
|
||||
$logger.debug register.inspect
|
||||
body = SUCCESS_TEMPLATE.result binding
|
||||
@distributor.distribute(to.to_response(list:, to:, body:))
|
||||
@distributor.distribute(mail.to_response(list: list, mail: mail, body: body))
|
||||
end
|
||||
|
||||
def handle_403(list:, to:)
|
||||
$logger.debug "Subscribe#handle_403 on #{list.email} for #{to.from}"
|
||||
def handle_403(list:, mail:)
|
||||
$logger.debug "Subscribe#handle_403 on #{list.email} for #{mail.from}"
|
||||
body = FORBIDDEN_TEMPLATE.result binding
|
||||
@distributor.distribute(to.to_response(list:, to:, body:))
|
||||
@distributor.distribute(mail.to_response(list: list, mail: mail, body: body))
|
||||
end
|
||||
end
|
||||
|
||||
class Unsubscribe < Action
|
||||
SUCCESS_TEMPLATE = Actions.template("unsubscribe.success")
|
||||
|
||||
def handle(list:, to:, attributes:)
|
||||
Email.unregister!(mailinglist: list, email: to.from)
|
||||
def handle(list:, mail:, attributes:)
|
||||
Email.unregister!(mailinglist: list, email: mail.from)
|
||||
body = SUCCESS_TEMPLATE.result binding
|
||||
@distributor.distribute(to.to_response(list:, to:, body:))
|
||||
@distributor.distribute(mail.to_response(list: list, mail: mail, body: body))
|
||||
end
|
||||
end
|
||||
|
||||
class Help < Action
|
||||
HELP_TEMPLATE = Actions.template("help")
|
||||
def handle(list:, to:, attributes:)
|
||||
|
||||
def handle(list:, mail:, attributes:)
|
||||
body = HELP_TEMPLATE.result binding
|
||||
@distributor.distribute(to.to_response(list:, to:, body:))
|
||||
@distributor.distribute(mail.to_response(list: list, mail: mail, body: body))
|
||||
end
|
||||
end
|
||||
|
||||
# This distribute the mail among the readers
|
||||
class Distribute < Action
|
||||
def handle(list:, to:, attributes:)
|
||||
if !list
|
||||
$logger.warn "invalid email writer for #{mail.from} on #{mail.to}"
|
||||
return nil
|
||||
def handle(list:, mail:, attributes:)
|
||||
if !list.enabled_writers.find { _1.email == mail.from }
|
||||
if list.registration?("autoregister")
|
||||
Email.register!(mailinglist: list, name: mail.from_name, email: mail.from).save
|
||||
else
|
||||
$logger.warn "invalid email writer for #{mail.from} on #{mail.to}"
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
list.enabled_readers.each do |reader|
|
||||
to_distrib = to.to_redistribute(list:, dest: reader)
|
||||
to_distrib = mail.to_redistribute(list: list, dest: reader)
|
||||
@distributor.distribute(to_distrib)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
You have subscribed to <%= list.name %> <<%= list.email %>>
|
||||
|
||||
Your current permissions are <%= register.permissions.to_s(2).rjust(8, "0") %>
|
||||
Your current permissions are <%= register.permissions_words.join(', ') %>
|
|
@ -6,8 +6,8 @@ class Mailinglist < Sequel::Model($db)
|
|||
HOST = ENV["MAILINGLIST_HOST"]
|
||||
|
||||
STRATEGIES = {
|
||||
registration: %w[free validated closed],
|
||||
moderate: %w[freewrite restrictedwrite],
|
||||
registration: %w[autoregister free validated closed],
|
||||
moderation: %w[freewrite restrictedwrite],
|
||||
}.freeze
|
||||
|
||||
one_to_many :emails
|
||||
|
@ -23,7 +23,7 @@ class Mailinglist < Sequel::Model($db)
|
|||
end
|
||||
|
||||
def self.build(name:, aliasing: nil, suffix: nil, strategy: "closed")
|
||||
email = "#{BASE_USER}"
|
||||
email = BASE_USER.dup
|
||||
email << SUFFIX_SEPARATOR << suffix if suffix
|
||||
aliasing = UUID.generate if !suffix && !aliasing
|
||||
email << aliasing if aliasing
|
||||
|
@ -48,27 +48,35 @@ class Mailinglist < Sequel::Model($db)
|
|||
end
|
||||
|
||||
def registration
|
||||
strategy.split("|").select { STRATEGIES[:registration].include(_1) }
|
||||
strategy.split("|").filter { STRATEGIES[:registration].include?(_1) }
|
||||
end
|
||||
|
||||
def registration?(find)
|
||||
registration.include?(find)
|
||||
end
|
||||
|
||||
def moderation
|
||||
strategy.split("|").select { STRATEGIES[:registration].include(_1) }
|
||||
strategy.split("|").filter { STRATEGIES[:moderation].include?(_1) }
|
||||
end
|
||||
|
||||
def moderation?(find)
|
||||
moderation.include?(find)
|
||||
end
|
||||
|
||||
def enabled_readers
|
||||
emails.filter{ _1.permissions & Email::Permissions::READ != 0 }
|
||||
emails.filter { _1.permissions & Email::Permissions::READ != 0 }
|
||||
end
|
||||
|
||||
def enabled_writers
|
||||
emails.filter{ _1.permissions & Email::Permissions::WRITE != 0 }
|
||||
emails.filter { _1.permissions & Email::Permissions::WRITE != 0 }
|
||||
end
|
||||
|
||||
def enabled_admins
|
||||
emails.filter{ _1.permissions & Email::Permissions::ADMIN != 0 }
|
||||
emails.filter { _1.permissions & Email::Permissions::ADMIN != 0 }
|
||||
end
|
||||
|
||||
def enabled_modos
|
||||
emails.filter{ _1.permissions & Email::Permissions::MODO != 0 }
|
||||
emails.filter { _1.permissions & Email::Permissions::MODO != 0 }
|
||||
end
|
||||
|
||||
def actions_emails
|
||||
|
@ -100,9 +108,7 @@ class Mailinglist < Sequel::Model($db)
|
|||
end
|
||||
|
||||
def set_permissions_email(*permissions_symbols, user_email: nil, permissions: nil)
|
||||
if permissions.nil?
|
||||
permissions = Email::Permissions.from_symbols(*permissions_symbols)
|
||||
end
|
||||
permissions = Email::Permissions.from_symbols(*permissions_symbols) if permissions.nil?
|
||||
user_part = user_email ? ",user-email=#{user_email}" : ""
|
||||
permissions_part = ",permissions=#{permissions}"
|
||||
"#{email}?subject=set-permissions#{user_part}#{permissions_part}"
|
||||
|
@ -112,5 +118,4 @@ class Mailinglist < Sequel::Model($db)
|
|||
"#{email}?subject=list-users"
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -78,7 +78,7 @@ class Protocols::Mail
|
|||
["List-Post", "<mailto:#{list.post_email}>"],
|
||||
["List-Owner", "<mailto:#{list.owner_email}>"],
|
||||
["In-Reply-To", @message_id],
|
||||
["Precedence", "list"],
|
||||
%w[Precedence list],
|
||||
# ["Precedence", "bulk"],
|
||||
["Message-Id", "<#{UUID.generate}@#{ENV['SENDER_HOST']}>"],
|
||||
["X-Sequence", (@seq + 1).to_s],
|
||||
|
@ -124,8 +124,8 @@ class Protocols::Mail
|
|||
# Create a response email for an existing one.
|
||||
#
|
||||
# @param list [Mailinglist]
|
||||
# @param to [Protocols::Mail]
|
||||
def to_response(list:, to:, body:)
|
||||
# @param mail [Protocols::Mail]
|
||||
def to_response(list:, mail:, body:)
|
||||
new = clone
|
||||
new.replace_headers!(
|
||||
["User-Agent", USER_AGENT],
|
||||
|
@ -139,7 +139,7 @@ class Protocols::Mail
|
|||
["Message-Id", "<#{UUID.generate}@#{ENV['SENDER_HOST']}>"],
|
||||
)
|
||||
|
||||
new.to = to.from
|
||||
new.to = mail.from
|
||||
new.from = list.email
|
||||
new.body = "#{body}#{list.signature}"
|
||||
new
|
||||
|
|
Loading…
Reference in New Issue