Make describe_domain work (for DovecotMailstore) even after a domain is removed.
[mailshears.git] / src / plugins / dovecot_mailstore.rb
1 require 'src/errors'
2 require 'src/filesystem'
3 require 'src/mailstore'
4 require 'src/plugin'
5
6 class DovecotMailstore < Mailstore
7
8 include Plugin
9
10 def initialize
11 @domain_root = Configuration::MAIL_ROOT
12 end
13
14 def describe_domain(domain)
15 begin
16 domain_path = get_domain_path(domain)
17 return domain_path
18 rescue NonexistentDomainError => e
19 return e.message
20 end
21 end
22
23 def describe_account(account)
24 begin
25 account_path = get_account_path(account)
26 return account_path
27 rescue NonexistentAccountError => e
28 return e.message
29 end
30 end
31
32 def delete_domain(domain)
33 domain_path = self.get_domain_path(domain)
34 FileUtils.rm_rf(domain_path)
35 end
36
37 def delete_account(account)
38 account_path = self.get_account_path(account)
39 FileUtils.rm_rf(account_path)
40 end
41
42 def get_leftover_domains(db_domains)
43 # Get the list of domains according to the filesystem.
44 fs_domains = self.get_domains_from_filesystem()
45
46 # Return the list of domains on the filesystem that aren't in the DB.
47 return (fs_domains - db_domains)
48 end
49
50 def get_leftover_accounts(db_accounts)
51 # Get the list of accounts according to the filesystem.
52 fs_domains = self.get_domains_from_filesystem()
53 fs_accounts = self.get_accounts_from_filesystem(fs_domains)
54
55 # And return the accounts on the filesystem that aren't in the DB.
56 return (fs_accounts - db_accounts)
57 end
58
59 protected;
60
61 def get_domains_from_filesystem()
62 return Filesystem.get_subdirs(@domain_root)
63 end
64
65 def get_accounts_from_filesystem(domains)
66 accounts = []
67
68 domains.each do |domain|
69 begin
70 # Throws a NonexistentDomainError if the domain's path
71 # doesn't exist on the filesystem. In this case, we want
72 # to report zero accounts.
73 domain_path = get_domain_path(domain)
74 usernames = Filesystem.get_subdirs(domain_path)
75
76 usernames.each do |username|
77 accounts << "#{username}@#{domain}"
78 end
79 rescue NonexistentDomainError => e
80 # Party hard.
81 end
82 end
83
84 return accounts
85 end
86
87
88 def get_domain_path(domain)
89 # Return the filesystem path for the given domain.
90 # That is, the directory where its mail is stored.
91 # Only works if the domain directory exists!
92 domain_path = File.join(@domain_root, domain)
93
94 if File.directory?(domain_path)
95 return domain_path
96 else
97 raise NonexistentDomainError.new(domain_path)
98 end
99 end
100
101
102 def get_account_path(account)
103 # Return the filesystem path of this account's mailbox.
104 # Only works if the account exists!
105 if not account.include?('@')
106 raise InvalidAccountError.new("#{account}: Accounts must contain an '@' symbol.")
107 end
108
109 account_parts = account.split('@')
110 user_part = account_parts[0]
111 domain_part = account_parts[1]
112
113 domain_path = get_domain_path(domain_part)
114 account_path = File.join(domain_path, user_part)
115
116 if File.directory?(account_path)
117 return account_path
118 else
119 raise NonexistentAccountError.new(account_path)
120 end
121 end
122
123 end