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