def create(self): log = logging.getLogger('flscp') # create: # 1. update mail_users # 2. update credentials, if given # 3. update /etc/postfix/fls/mailboxes # 4. update aliases # 5. update sender-access (we could later be implement to restrict sending!) # postmap all relevant entries if self.exists(): # already exists! raise KeyError('Mail "%s@%s" already exists!' % (self.mail, self.domain)) # get domain id! (if not exist: create!) try: d = Domain.getByName(self.domain) except KeyError: raise # pw entered? if len(self.pw.strip()) > 0: self.hashPassword() db = MailDatabase.getInstance() cx = db.getCursor() query = ( 'INSERT INTO mail_users (mail_acc, mail_pass, mail_forward, domain_id, mail_type, status, quota, mail_addr, alternative_addr, enabled) ' \ 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' ) cx.execute( query, ( self.mail, self.hashPw, ','.join(self.forward), d.id, self.type, self.state, self.quota, '%s@%s' % (self.mail, self.domain), self.altMail, str(int(self.enabled)) ) ) db.commit() log.debug('executed mysql statement: %s' % (cx.statement,)) id = cx.lastrowid if id is None: cx.close() return False else: self.id = id # update credentials... self.updateCredentials() # now update mailboxes files! if not self.updateMailboxes(): cx.close() return False # update aliases if not self.updateAliases(): # remove entry from updateMailboxes? cx.close() return False # update sender-access if not self.updateSenderAccess(): # remove entry from updateMailboxes and Aliases ? cx.close() return False cx.close() # all best? Than go forward and update set state,... self.setState(MailAccount.STATE_OK) # notify if len(self.altMail) > 0: m = Mailer(self) state = False if self.type == MailAccount.TYPE_ACCOUNT \ or self.type == MailAccount.TYPE_FWDSMTP: state = m.newAccount() else: state = m.newForward() if state: log.info('User is notified about account change!') else: log.warning('Unknown error while notifying user!') else: log.info('User is not notified because we have no address of him!') # reset info self.pw = '' self.hashPw = '' self.genPw = False
def save(self): log = logging.getLogger('flscp') conf = FLSConfig.getInstance() if self.state == MailAccount.STATE_CREATE: self.create() return elif self.state == MailAccount.STATE_DELETE: self.delete() return elif self.state == MailAccount.STATE_QUOTA: self.recalculateQuota() return # now save! # -> see create - but if key changed (mail address!) remove # all entries before and rename folder in /var/mail,... directory # get original data! if not self.exists(): self.create() # get domain id! (if not exist: create!) try: d = Domain.getByName(self.domain) except KeyError: raise # pw entered? if len(self.pw.strip()) > 0: log.info('Hash password for user %s' % (self.mail,)) self.hashPassword() db = MailDatabase.getInstance() cx = db.getCursor() query = ('SELECT mail_id, mail_addr, mail_type FROM mail_users WHERE mail_id = %s') cx.execute(query, (self.id,)) (mail_id, mail_addr, mail_type) = cx.fetchone() (mail, domain) = mail_addr.split('@') cx.close() cx = db.getCursor() if (self.type == MailAccount.TYPE_ACCOUNT and self.hashPw != '') \ or (self.type == MailAccount.TYPE_FWDSMTP and self.hashPw != '') \ or self.type == MailAccount.TYPE_FORWARD: query = ( 'UPDATE mail_users SET mail_acc = %s, mail_pass = %s, mail_forward = %s, ' \ 'domain_id = %s, mail_type = %s, status = %s, quota = %s, mail_addr = %s, ' \ 'alternative_addr = %s, enabled = %s WHERE mail_id = %s' ) params = ( self.mail, self.hashPw, ','.join(self.forward), d.id, self.type, self.state, self.quota, '%s@%s' % (self.mail, self.domain), self.altMail, str(int(self.enabled)), self.id ) else: query = ( 'UPDATE mail_users SET mail_acc = %s, mail_forward = %s, ' \ 'domain_id = %s, mail_type = %s, status = %s, quota = %s, mail_addr = %s, ' \ 'alternative_addr = %s, enabled = %s WHERE mail_id = %s' ) params = ( self.mail, ','.join(self.forward), d.id, self.type, self.state, self.quota, '%s@%s' % (self.mail, self.domain), self.altMail, str(int(self.enabled)), self.id ) cx.execute( query, params ) db.commit() log.debug('executed mysql statement: %s' % (cx.statement,)) # update credentials... # if pw was entered or type changed if mail_type != self.type or self.pw.strip() != '': self.updateCredentials() # now update mailboxes files! if not self.updateMailboxes(oldMail=mail, oldDomain=domain): cx.close() return False # update aliases if not self.updateAliases(oldMail=mail, oldDomain=domain): # remove entry from updateMailboxes? cx.close() return False # update sender-access if not self.updateSenderAccess(oldMail=mail, oldDomain=domain): # remove entry from updateMailboxes and Aliases ? cx.close() return False # rename folders - but only if target directory does not exist # (we had to throw fatal error if target directory exists!) oldPath = '%s/%s/%s/' % (conf.get('mailserver', 'basemailpath'), domain, mail) path = '%s/%s/%s/' % (conf.get('mailserver', 'basemailpath'), self.domain, self.mail) if os.path.exists(oldPath): if os.path.exists(path): log.error('Could not move "%s" to "%s", because it already exists!' % (path,)) else: try: os.rename(oldPath, path) except OSError as e: log.warning('Got OSError - Does directory exists? (%s)' % (e,)) except Exception as e: log.warning('Got unexpected exception (%s)!' % (e,)) cx.close() # all best? Than go forward and update set state,... self.setState(MailAccount.STATE_OK) # notify if len(self.altMail) > 0: m = Mailer(self) state = False if self.type == MailAccount.TYPE_ACCOUNT \ or self.type == MailAccount.TYPE_FWDSMTP: state = m.changeAccount() else: state = m.changeForward() if state: log.info('User is notified about account change!') else: log.warning('Unknown error while notifying user!') else: log.info('User is not notified because we have no address of him!') # reset info self.pw = '' self.hashPw = '' self.genPw = False