28 from VirtualMailManager.Config import Config as Cfg |
28 from VirtualMailManager.Config import Config as Cfg |
29 from VirtualMailManager.Domain import Domain, get_gid |
29 from VirtualMailManager.Domain import Domain, get_gid |
30 from VirtualMailManager.EmailAddress import EmailAddress |
30 from VirtualMailManager.EmailAddress import EmailAddress |
31 from VirtualMailManager.errors import \ |
31 from VirtualMailManager.errors import \ |
32 DomainError, NotRootError, PermissionError, VMMError |
32 DomainError, NotRootError, PermissionError, VMMError |
|
33 from VirtualMailManager.mailbox import new as new_mailbox |
|
34 from VirtualMailManager.pycompat import any |
33 from VirtualMailManager.Relocated import Relocated |
35 from VirtualMailManager.Relocated import Relocated |
34 from VirtualMailManager.Transport import Transport |
36 from VirtualMailManager.Transport import Transport |
35 |
37 |
36 |
38 |
37 _ = lambda msg: msg |
39 _ = lambda msg: msg |
38 |
40 |
39 RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$""" |
41 RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$""" |
40 RE_MBOX_NAMES = """^[\x20-\x25\x27-\x7E]*$""" |
|
41 TYPE_ACCOUNT = 0x1 |
42 TYPE_ACCOUNT = 0x1 |
42 TYPE_ALIAS = 0x2 |
43 TYPE_ALIAS = 0x2 |
43 TYPE_RELOCATED = 0x4 |
44 TYPE_RELOCATED = 0x4 |
44 OTHER_TYPES = { |
45 OTHER_TYPES = { |
45 TYPE_ACCOUNT: (_(u'an account'), ERR.ACCOUNT_EXISTS), |
46 TYPE_ACCOUNT: (_(u'an account'), ERR.ACCOUNT_EXISTS), |
245 os.umask(0007) |
246 os.umask(0007) |
246 self.__makedir(domdirdirs[1], self._Cfg.dget('domain.directory_mode'), |
247 self.__makedir(domdirdirs[1], self._Cfg.dget('domain.directory_mode'), |
247 0, gid) |
248 0, gid) |
248 os.chdir(oldpwd) |
249 os.chdir(oldpwd) |
249 |
250 |
250 def __subscribe(self, folderlist, uid, gid): |
251 def __make_home(self, account): |
251 """Creates a subscriptions file with the mailboxes from `folderlist`""" |
252 """Create a home directory for the new Account *account*.""" |
252 fname = os.path.join(self._Cfg.dget('maildir.name'), 'subscriptions') |
|
253 sf = open(fname, 'w') |
|
254 sf.write('\n'.join(folderlist)) |
|
255 sf.write('\n') |
|
256 sf.flush() |
|
257 sf.close() |
|
258 os.chown(fname, uid, gid) |
|
259 os.chmod(fname, 384) |
|
260 |
|
261 def __mailDirMake(self, domdir, uid, gid): |
|
262 """Creates maildirs and maildir subfolders. |
|
263 |
|
264 Keyword arguments: |
|
265 domdir -- the path to the domain directory |
|
266 uid -- user id from the account |
|
267 gid -- group id from the account |
|
268 """ |
|
269 # obsolete -> (mailbox / maillocation) |
|
270 return |
|
271 os.umask(0007) |
253 os.umask(0007) |
272 oldpwd = os.getcwd() |
254 os.chdir(account.domain_directory) |
273 os.chdir(domdir) |
255 os.mkdir('%s' % account.uid, self._Cfg.dget('account.directory_mode')) |
274 |
256 os.chown('%s' % account.uid, account.uid, account.gid) |
275 maildir = self._Cfg.dget('maildir.name') |
|
276 folders = [maildir] |
|
277 append = folders.append |
|
278 for folder in self._Cfg.dget('maildir.folders').split(':'): |
|
279 folder = folder.strip() |
|
280 if len(folder) and not folder.count('..'): |
|
281 if re.match(RE_MBOX_NAMES, folder): |
|
282 append('%s/.%s' % (maildir, folder)) |
|
283 else: |
|
284 self.__warnings.append(_('Skipped mailbox folder: %r') % |
|
285 folder) |
|
286 else: |
|
287 self.__warnings.append(_('Skipped mailbox folder: %r') % |
|
288 folder) |
|
289 |
|
290 subdirs = ['cur', 'new', 'tmp'] |
|
291 mode = self._Cfg.dget('account.directory_mode') |
|
292 |
|
293 self.__makedir('%s' % uid, mode, uid, gid) |
|
294 os.chdir('%s' % uid) |
|
295 for folder in folders: |
|
296 self.__makedir(folder, mode, uid, gid) |
|
297 for subdir in subdirs: |
|
298 self.__makedir(os.path.join(folder, subdir), mode, uid, gid) |
|
299 self.__subscribe((f.replace(maildir + '/.', '') for f in folders[1:]), |
|
300 uid, gid) |
|
301 os.chdir(oldpwd) |
|
302 |
257 |
303 def __userDirDelete(self, domdir, uid, gid): |
258 def __userDirDelete(self, domdir, uid, gid): |
304 if uid > 0 and gid > 0: |
259 if uid > 0 and gid > 0: |
305 userdir = '%s' % uid |
260 userdir = '%s' % uid |
306 if userdir.count('..') or domdir.count('..'): |
261 if userdir.count('..') or domdir.count('..'): |
388 dom.update_transport(trsp) |
343 dom.update_transport(trsp) |
389 else: |
344 else: |
390 dom.update_transport(trsp, force=True) |
345 dom.update_transport(trsp, force=True) |
391 |
346 |
392 def domainDelete(self, domainname, force=None): |
347 def domainDelete(self, domainname, force=None): |
393 if not force is None and force not in ['deluser', 'delalias', |
348 if force and force not in ('deluser', 'delalias', 'delall'): |
394 'delall']: |
349 raise DomainError(_(u"Invalid argument: '%s'") % force, |
395 raise DomainError(_(u'Invalid argument: ā%sā') % |
350 ERR.INVALID_OPTION) |
396 force, ERR.INVALID_OPTION) |
|
397 dom = self.__getDomain(domainname) |
351 dom = self.__getDomain(domainname) |
398 gid = dom.gid |
352 gid = dom.gid |
399 domdir = dom.directory |
353 domdir = dom.directory |
400 if self._Cfg.dget('domain.force_deletion') or force == 'delall': |
354 if self._Cfg.dget('domain.force_deletion') or force == 'delall': |
401 dom.delete(True, True) |
355 dom.delete(True, True) |
495 def user_add(self, emailaddress, password): |
449 def user_add(self, emailaddress, password): |
496 """Wrapper around Account.set_password() and Account.save().""" |
450 """Wrapper around Account.set_password() and Account.save().""" |
497 acc = self.__getAccount(emailaddress) |
451 acc = self.__getAccount(emailaddress) |
498 acc.set_password(password) |
452 acc.set_password(password) |
499 acc.save() |
453 acc.save() |
500 # depends on modules mailbox and maillocation |
454 oldpwd = os.getcwd() |
501 # self.__mailDirMake(acc.domain_directory, acc.uid, acc.gid) |
455 self.__make_home(acc) |
|
456 mailbox = new_mailbox(acc) |
|
457 mailbox.create() |
|
458 folders = self._Cfg.dget('mailbox.folders').split(':') |
|
459 if any(folders): |
|
460 bad = mailbox.add_boxes(folders, |
|
461 self._Cfg.dget('mailbox.subscribe')) |
|
462 if bad: |
|
463 self.__warnings.append(_(u"Skipped mailbox folders:") + |
|
464 '\n\t- ' + '\n\t- '.join(bad)) |
|
465 os.chdir(oldpwd) |
502 |
466 |
503 def aliasAdd(self, aliasaddress, *targetaddresses): |
467 def aliasAdd(self, aliasaddress, *targetaddresses): |
504 """Creates a new `Alias` entry for the given *aliasaddress* with |
468 """Creates a new `Alias` entry for the given *aliasaddress* with |
505 the given *targetaddresses*.""" |
469 the given *targetaddresses*.""" |
506 alias = self.__getAlias(aliasaddress) |
470 alias = self.__getAlias(aliasaddress) |