mailinglist.rb/lib/models/email.rb

108 lines
2.4 KiB
Ruby

class Email < Sequel::Model($db)
many_to_one :mailinglist
def before_create
self.created_at ||= Time.now
super
end
def before_save
self.updated_at ||= Time.now
super
end
module Permissions
NONE = 0 # 0
READ = 2**0 # 1
WRITE = 2**1 # 2
OP = 2**2 # 4
MODO = 2**3 # 8
ALL = READ | WRITE | OP | MODO
WORDS = {
READ => "reader",
WRITE => "writer",
OP => "operator",
MODO => "modo",
}.freeze
FROM_SYMBOLS = {
reader: READ,
writer: WRITE,
operator: OP,
modo: MODO,
none: NONE,
}
def self.from_symbols(*syms)
syms.map { FROM_SYMBOLS[_1] }.sum
end
def self.op?(perm)
perm & OP == OP
end
end
def permissions?(ask)
(permissions & ask) == ask
end
def reader?
permissions?(Permissions::READ)
end
def writer?
permissions?(Permissions::WRITE)
end
def op?
permissions?(Permissions::OP)
end
def modo?
permissions?(Permissions::MODO)
end
def permissions_words
words = Permissions::WORDS.filter { permissions?(_1) }.values
words << "none" if words.empty?
words
end
# Adds a new email to a ML, and respect the ML strategy.
# Registers with full permissions if first subscribe.
#
# @param name
# @param email
# @param mailinglist required if mailinglist.nil?
# @param mailinglist_id required if mailinglist.nil?
def self.register!(name:, email:, mailinglist: nil, mailinglist_id: nil)
mailinglist = Mailinglist.first(id: mailinglist_id) if mailinglist.nil?
if mailinglist.nil?
$logger.error "No mailing list found with id=#{mailinglist_id}"
raise "No mailinglist #{mailinglist_id}"
end
permissions =
if mailinglist.emails.count == 0
Permissions::ALL
elsif mailinglist.registration == "free"
Permissions::READ | Permissions::WRITE
elsif mailinglist.registration == "validated"
Permissions::NONE
elsif mailinglist.registration == "closed"
$logger.warn "Forbidden register for #{mailinglist.id}"
return nil # not valid
end
$logger.debug { "Existing users: #{mailinglist.emails.map(&:email).join(', ')}" }
new(
name: name,
email: email,
mailinglist: mailinglist,
permissions: permissions,
).save
end
def self.unregister!(mailinglist:, email:)
Email.where(mailinglist: mailinglist, email: email).delete
end
end