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