702b621ff5da9c1ee18ccbd0fd29352950a63386
[mailshears.git] / lib / common / plugin.rb
1 require 'common/domain'
2 require 'common/user'
3
4 # All plugins should include this module. It defines the basic
5 # operations that all plugins are supposed to support.
6 module Plugin
7
8 module Run
9 # Module methods, meant to be extended. Includers can explicitly
10 # extend this to get a run() method defined in terms of their own
11 # runner() and dummy_runner() methods.
12
13 def included(c)
14 # Callback, called whenever another class or module includes this
15 # one. The parameter given is the name of the class or module
16 # that included us.
17 @includers ||= []
18 @includers << c
19 end
20
21 def includers
22 @includers ||= []
23 return @includers
24 end
25
26 def runner()
27 # The Runner associated with this plugin.
28 raise NotImplementedError
29 end
30
31 def dummy_runner()
32 # The DummyRunner associated with this plugin.
33 raise NotImplementedError
34 end
35
36 def run(cfg, *args)
37 includers().each do |includer|
38 plugin = includer.new(cfg)
39
40 if cfg.i_mean_business then
41 runner = runner().new()
42 else
43 runner = dummy_runner().new()
44 end
45
46 # The splat passes the correct (we hope) number of arguments to the
47 # appropriate runner. The Rm(Dummy)Runner have splats on their
48 # *target arguments as well, to turn ARGV back into an array.
49 runner.run(plugin, *args)
50 end
51 end
52 end
53
54 def describe(target)
55 # A generic version of describe_user/describe_domain that
56 # dispatches base on the class of the target.
57 if target.is_a?(User)
58 if user_exists(target) then
59 return describe_user(target)
60 else
61 return 'User not found'
62 end
63 elsif target.is_a?(Domain)
64 if domain_exists(target) then
65 return describe_domain(target)
66 else
67 return 'Domain not found'
68 end
69 else
70 raise NotImplementedError
71 end
72 end
73
74 def describe_domain(domain)
75 # Provide a "description" of the domain. This is output along with
76 # the domain name and can be anything of use to the system
77 # administrator. The default doesn't do anything useful and should
78 # be overridden.
79 return domain.to_s()
80 end
81
82 def describe_user(user)
83 # Provide a "description" of the user. This is output along
84 # with the domain name and can be anything of use to the system
85 # administrator. The default doesn't do anything useful and should
86 # be overridden.
87 return user.to_s()
88 end
89
90 def list_users()
91 # Return a list of all users managed by this plugin.
92 raise NotImplementedError
93 end
94
95 def list_domains()
96 # Compute the domains from a list of users. Obviously much worse
97 # than getting the domains the "smart" way, if such a way exists.
98 users = list_users()
99 domains = users.map{ |u| u.domain() }
100 return domains.uniq()
101 end
102
103 def user_exists(user)
104 # Does the given username exist for this plugin? We use a naive
105 # implementation here based on list_users() which is required to
106 # exist above. Plugins can override this with something fast.
107 users = list_users()
108 return users.include?(user)
109 end
110
111 def domain_exists(domain)
112 # Does the given domain exist for this plugin? We use a naive
113 # implementation here based on list_domains() which is required to
114 # exist above. Plugins can override this with something fast.
115 domains = list_domains()
116 return domains.include?(domain)
117 end
118
119 def list_domains_users(domains)
120 # Get all users belonging to the given domains. If a user has
121 # domainpart "example.com" then it belongs to the domain
122 # "example.com".
123 #
124 # This uses a naive loop, but relies only on the existence of a
125 # list_users() method which is guaranteed above. More efficient
126 # implementations can usually be made within the plugin.
127 domains_users = []
128
129 users = list_users();
130 domains.each do |d|
131 matches = users.select do |user|
132 user.domainpart() == d.to_s()
133 end
134
135 domains_users += matches
136 end
137
138 return domains_users
139 end
140
141 end