require 'common/domain' require 'common/user' # All plugins should include this module. It defines the basic # operations that all plugins are supposed to support. module Plugin module Run # Module methods, meant to be extended. Includers can explicitly # extend this to get a run() method defined in terms of their own # runner() and dummy_runner() methods. def included(c) # Callback, called whenever another class or module includes this # one. The parameter given is the name of the class or module # that included us. @includers ||= [] @includers << c end def includers @includers ||= [] return @includers end def runner() # The Runner associated with this plugin. raise NotImplementedError end def dummy_runner() # The DummyRunner associated with this plugin. raise NotImplementedError end def run(cfg, *args) includers().each do |includer| plugin = includer.new(cfg) if cfg.i_mean_business then runner = runner().new() else runner = dummy_runner().new() end # The splat passes the correct (we hope) number of arguments to the # appropriate runner. The Rm(Dummy)Runner have splats on their # *target arguments as well, to turn ARGV back into an array. runner.run(plugin, *args) end end end def describe(target) # A generic version of describe_user/describe_domain that # dispatches base on the class of the target. if target.is_a?(User) if user_exists(target) then return describe_user(target) else return 'User not found' end elsif target.is_a?(Domain) if domain_exists(target) then return describe_domain(target) else return 'Domain not found' end else raise NotImplementedError end end def describe_domain(domain) # Provide a "description" of the domain. This is output along with # the domain name and can be anything of use to the system # administrator. The default doesn't do anything useful and should # be overridden. return domain.to_s() end def describe_user(user) # Provide a "description" of the user. This is output along # with the domain name and can be anything of use to the system # administrator. The default doesn't do anything useful and should # be overridden. return user.to_s() end def list_users() # Return a list of all users managed by this plugin. raise NotImplementedError end def list_domains() # Compute the domains from a list of users. Obviously much worse # than getting the domains the "smart" way, if such a way exists. users = list_users() domains = users.map{ |u| u.domain() } return domains.uniq() end def user_exists(user) # Does the given username exist for this plugin? We use a naive # implementation here based on list_users() which is required to # exist above. Plugins can override this with something fast. users = list_users() return users.include?(user) end def domain_exists(domain) # Does the given domain exist for this plugin? We use a naive # implementation here based on list_domains() which is required to # exist above. Plugins can override this with something fast. domains = list_domains() return domains.include?(domain) end def list_domains_users(domains) # Get all users belonging to the given domains. If a user has # domainpart "example.com" then it belongs to the domain # "example.com". # # This uses a naive loop, but relies only on the existence of a # list_users() method which is guaranteed above. More efficient # implementations can usually be made within the plugin. domains_users = [] users = list_users(); domains.each do |d| matches = users.select do |user| user.domainpart() == d.to_s() end domains_users += matches end return domains_users end end