def initialize(self): "Set the initial values for the new document." try: self.doc['owner'] = self.rqh.current_user['email'] except (TypeError, AttributeError, KeyError): self.doc['owner'] = None self.doc['created'] = utils.timestamp()
def enable_accounts(db): view = db.view('account/status', include_docs=True, key=constants.PENDING) for row in view: account = row.doc account['status'] = constants.ENABLED account['password'] = None account['code'] = utils.get_iuid() account['modified'] = utils.timestamp() db.save(account) utils.log(db, None, account, changed=dict(password=None, status=constants.ENABLED)) # Prepare message to send later try: template = settings['ACCOUNT_MESSAGES']['enabled'] except KeyError: pass else: with MessageSaver(db=db) as saver: saver.set_params( account=account['email'], password_url=absolute_reverse_url('password'), password_code_url=absolute_reverse_url( 'password', email=account['email'], code=account['code']), code=account['code']) saver.set_template(template) saver['recipients'] = [account['email']] print(account['email']) time.sleep(PAUSE)
def send(self, recipients): "Send the message to the given recipient email addresses." try: self['recipients'] = recipients try: host = settings['EMAIL']['HOST'] except KeyError: return try: port = settings['EMAIL']['PORT'] except KeyError: server = smtplib.SMTP(host) else: server = smtplib.SMTP(host, port=port) if settings['EMAIL'].get('TLS'): server.starttls() try: user = settings['EMAIL']['USER'] password = settings['EMAIL']['PASSWORD'] except KeyError: pass else: server.login(user, password) mail = email.mime.text.MIMEText(self['text'], 'plain', 'utf-8') mail['Subject'] = self['subject'] mail['From'] = self['sender'] for recipient in self['recipients']: mail['To'] = recipient server.sendmail(self['sender'], self['recipients'], mail.as_string()) self['sent'] = utils.timestamp() except Exception as msg: self['error'] = str(msg) logging.error("email failed to %s: %s", self['recipients'], msg) raise
def enable_accounts(db): view = db.view('account/status', include_docs=True, key=constants.PENDING) for row in view: account = row.doc account['status'] = constants.ENABLED account['password'] = None account['code'] = utils.get_iuid() account['modified'] = utils.timestamp() db.save(account) utils.log(db, None, account, changed=dict(password=None, status=constants.ENABLED)) # Prepare message to send later try: template = settings['ACCOUNT_MESSAGES']['enabled'] except KeyError: pass else: with MessageSaver(db=db) as saver: saver.set_params(account=account['email'], password_url=absolute_reverse_url('password'), password_code_url=absolute_reverse_url( 'password', email=account['email'], code=account['code']), code=account['code']) saver.set_template(template) saver['recipients'] = [account['email']] print(account['email']) time.sleep(PAUSE)
def print_log(self, message): if not self.banner_printed: print('Messenger', utils.timestamp()) if self.dry_run: print('*** Dry run only! ***') self.banner_printed = True print(u"sent email '{0}' to {1}".format( message['subject'], ', '.join(message['recipients'])).encode('utf-8'))
def get(self): "CSV file output." self.check_staff() self.set_filter() accounts = self.get_accounts() csvfile = StringIO() writer = csv.writer(csvfile) safe = utils.csv_safe_row writer.writerow(safe((settings['SITE_NAME'], utils.timestamp()))) writer.writerow( safe(('Email', 'Last name', 'First name', 'Role', 'Status', 'Order count', 'University', 'Department', 'PI', 'Gender', 'Group size', 'Subject', 'Address', 'Zip', 'City', 'Country', 'Invoice ref', 'Invoice address', 'Invoice zip', 'Invoice city', 'Invoice country', 'Phone', 'Other data', 'Latest login', 'Modified', 'Created'))) for account in accounts: addr = account.get('address') or dict() iaddr = account.get('invoice_address') or dict() try: subject = "{0}: {1}".format( account.get('subject'), settings['subjects_lookup'][account.get('subject')]) except KeyError: subject = '' row = [ utils.to_utf8(account['email']), utils.to_utf8(account.get('last_name') or ''), utils.to_utf8(account.get('first_name') or ''), account['role'], account['status'], account['order_count'], utils.to_utf8(account.get('university') or ''), utils.to_utf8(account.get('department') or ''), account.get('pi') and 'yes' or 'no', account.get('gender') or '', account.get('group_size') or '', subject, utils.to_utf8(addr.get('address') or ''), utils.to_utf8(addr.get('zip') or ''), utils.to_utf8(addr.get('city') or ''), utils.to_utf8(addr.get('country') or ''), utils.to_utf8(account.get('invoice_ref') or ''), utils.to_utf8(iaddr.get('address') or ''), utils.to_utf8(iaddr.get('zip') or ''), utils.to_utf8(iaddr.get('city') or ''), utils.to_utf8(iaddr.get('country') or ''), utils.to_utf8(account.get('phone') or ''), utils.to_utf8(account.get('other_data') or ''), utils.to_utf8(account.get('login') or ''), utils.to_utf8(account.get('modified') or ''), utils.to_utf8(account.get('created') or '') ] writer.writerow(safe(row)) self.write(csvfile.getvalue()) self.set_header('Content-Type', constants.CSV_MIME) self.set_header('Content-Disposition', 'attachment; filename="accounts.csv"')
def process(self): "Go through unsent messages, and send them." view = self.db.view('message/unsent', include_docs=True) for row in view: message = row.doc if self.dry_run: self.print_log(message) else: self.send_email(message) with MessageSaver(doc=message, db=self.db) as saver: saver['sent'] = utils.timestamp()
def post(self): try: account = self.get_account(self.get_argument('email', '')) except ValueError as msg: self.see_other('home', error=str(msg)) return if account.get('code') != self.get_argument('code'): self.see_other('home', error="Either the email address or the code" + " for setting password was wrong." + " Try to request a new code using the" + " 'Reset password' button.") return password = self.get_argument('password', '') try: utils.check_password(password) except ValueError as msg: self.see_other('password', email=self.get_argument('email') or '', code=self.get_argument('code') or '', error=str(msg)) return if password != self.get_argument('confirm_password'): self.see_other('password', email=self.get_argument('email') or '', code=self.get_argument('code') or '', error='password confirmation failed. Not the same!') return with AccountSaver(doc=account, rqh=self) as saver: saver.set_password(password) saver['login'] = utils.timestamp() # Set login session. self.set_secure_cookie(constants.USER_COOKIE, account['email'], expires_days=settings['LOGIN_MAX_AGE_DAYS']) if account.get('update_info'): self.see_other( 'account_edit', account['email'], message='Please review and update your account information.') else: self.see_other('home')
def finalize(self): "Perform any final modifications before saving the document." self.doc['modified'] = utils.timestamp()
class Login(RequestHandler): "Login to a account account. Set a secure cookie." def get(self): self.render('login.html', next=self.get_argument('next', None)) def post(self): """Login to a account account. Set a secure cookie. Forward to account edit page if first login. Log failed login attempt. Disable account if too many recent. """ try: email = self.get_argument('email') password = self.get_argument('password') except tornado.web.MissingArgumentError: self.see_other('home', error='Missing email or password argument.') return msg = 'Sorry, no such account or invalid password.' try: account = self.get_account(email) except ValueError, msg: self.see_other('home', error=str(msg)) return if utils.hashed_password(password) != account.get('password'): utils.log(self.db, self, account, changed=dict(login_failure=account['email'])) view = self.db.view('log/login_failure', startkey=[account['_id'], utils.timestamp(-1)], endkey=[account['_id'], utils.timestamp()]) if len(list(view)) > settings['LOGIN_MAX_FAILURES']: logging.warning( "account %s has been disabled due to" " too many login failures", account['email']) with AccountSaver(doc=account, rqh=self) as saver: saver['status'] = constants.DISABLED saver.erase_password() msg = 'Too many failed login attempts: Your account has been' \ ' disabled. You must contact the site administrators.' # Prepare message sent by cron job script 'script/messenger.py' try: template = self.db['account_messages']['disabled'] except KeyError: pass else: with MessageSaver(rqh=self) as saver: saver.set_params() saver.set_template(template) saver['recipients'] = [account['email']] self.see_other('home', error=msg) return try: if not account.get('status') == constants.ENABLED: raise ValueError except ValueError: self.see_other('home', error='Account is disabled.' ' Contact the site admin.') return if not self.global_modes['allow_login'] \ and account['role'] != constants.ADMIN: self.see_other('home', error='Login is currently disabled.') return self.set_secure_cookie(constants.USER_COOKIE, account['email'], expires_days=settings['LOGIN_MAX_AGE_DAYS']) with AccountSaver(doc=account, rqh=self) as saver: saver['login'] = utils.timestamp() # Set login timestamp. if account.get('update_info'): self.see_other( 'account_edit', account['email'], message='Please review and update your account information.') return next = self.get_argument('next', None) if next is None: self.see_other('home') else: # Not quite right: should be an absolute URL to redirect. # But seems to work anyway. self.redirect(next)
def post(self): """Login to a account account. Set a secure cookie. Forward to account edit page if first login. Log failed login attempt. Disable account if too many recent. """ try: email = self.get_argument('email') password = self.get_argument('password') except tornado.web.MissingArgumentError: self.see_other('home', error='Missing email or password argument.') return msg = 'Sorry, no such account or invalid password.' try: account = self.get_account(email) except ValueError as msg: self.see_other('home', error=str(msg)) return if utils.hashed_password(password) != account.get('password'): utils.log(self.db, self, account, changed=dict(login_failure=account['email'])) view = self.db.view('log/login_failure', startkey=[account['_id'], utils.timestamp(-1)], endkey=[account['_id'], utils.timestamp()]) # Disable account if too many recent login failures. if len(list(view)) > settings['LOGIN_MAX_FAILURES']: logging.warning( "account %s has been disabled due to" " too many login failures", account['email']) with AccountSaver(doc=account, rqh=self) as saver: saver['status'] = constants.DISABLED saver.erase_password() msg = "Too many failed login attempts: Your account has been" \ " disabled. Contact the site administrator %s." % \ settings.get('SITE_SUPPORT_EMAIL', '') # Prepare email message try: template = settings['ACCOUNT_MESSAGES'][constants.DISABLED] except KeyError: pass else: with MessageSaver(rqh=self) as saver: saver.create(template) # Recipient is hardwired here. saver.send([account['email']]) self.see_other('home', error=msg) return try: if not account.get('status') == constants.ENABLED: raise ValueError except ValueError: msg = "Account is disabled. Contact the site administrator %s." % \ settings.get('SITE_SUPPORT_EMAIL', '') self.see_other('home', error=msg) return if not self.global_modes['allow_login'] \ and account['role'] != constants.ADMIN: self.see_other('home', error='Login is currently disabled.') return self.set_secure_cookie(constants.USER_COOKIE, account['email'], expires_days=settings['LOGIN_MAX_AGE_DAYS']) logging.info("Basic auth login: account %s", account['email']) with AccountSaver(doc=account, rqh=self) as saver: saver['login'] = utils.timestamp() # Set login timestamp. if account.get('update_info'): self.see_other( 'account_edit', account['email'], message='Please review and update your account information.') return next = self.get_argument('next', None) if next is None: self.see_other('home') else: # Not quite right: should be an absolute URL to redirect. # But seems to work anyway. self.redirect(next)
if saver['history'] != old_order['history']: saver.changed['history'] = saver['history'] if current: # Using the call 'set_status' ensures that a message is # generated for sending to the user, when so configured. saver.set_status(current, date=current_date) print('Updated information for', portal_id) def regenerate_view(db, viewname): "Trigger CouchDB to regenerate the view by accessing it." view = db.view(viewname) for row in view: break if __name__ == '__main__': print(utils.timestamp()) parser = utils.get_command_line_parser(description= 'Load project info from Clarity LIMS into OrderPortal.') parser.add_option('-d', '--dryrun', action="store_true", dest="dryrun", default=False, help='dry run: no changes stored') (options, args) = parser.parse_args() utils.load_settings(filepath=options.settings) db = utils.get_db() orders_lookup = get_orders(db) clarity = Clarity() clarity_projects = clarity.get_all_projects() for project in clarity_projects:
if current: # Using the call 'set_status' ensures that a message is # generated for sending to the user, when so configured. saver.set_status(current, date=current_date) print('Updated information for', portal_id) def regenerate_view(db, viewname): "Trigger CouchDB to regenerate the view by accessing it." view = db.view(viewname) for row in view: break if __name__ == '__main__': print(utils.timestamp()) parser = utils.get_command_line_parser( description='Load project info from Clarity LIMS into OrderPortal.') parser.add_option('-d', '--dryrun', action="store_true", dest="dryrun", default=False, help='dry run: no changes stored') (options, args) = parser.parse_args() utils.load_settings(filepath=options.settings) db = utils.get_db() orders_lookup = get_orders(db) clarity = Clarity()
utils.check_password(password) except ValueError, msg: self.see_other('password', email=self.get_argument('email') or '', code=self.get_argument('code') or '', error=str(msg)) return if password != self.get_argument('confirm_password'): self.see_other('password', email=self.get_argument('email') or '', code=self.get_argument('code') or '', error='password confirmation failed. Not the same!') return with AccountSaver(doc=account, rqh=self) as saver: saver.set_password(password) saver['login'] = utils.timestamp() # Set login session. self.set_secure_cookie(constants.USER_COOKIE, account['email'], expires_days=settings['LOGIN_MAX_AGE_DAYS']) if account.get('update_info'): self.see_other( 'account_edit', account['email'], message='Please review and update your account information.') else: self.see_other('home') class Register(RequestHandler): "Register a new account account."
utils.check_password(password) except ValueError, msg: self.see_other('password', email=self.get_argument('email') or '', code=self.get_argument('code') or '', error=str(msg)) return if password != self.get_argument('confirm_password'): self.see_other('password', email=self.get_argument('email') or '', code=self.get_argument('code') or '', error='password confirmation failed. Not the same!') return with AccountSaver(doc=account, rqh=self) as saver: saver.set_password(password) saver['login'] = utils.timestamp() # Set login session. self.set_secure_cookie(constants.USER_COOKIE, account['email'], expires_days=settings['LOGIN_MAX_AGE_DAYS']) if account.get('update_info'): self.see_other('account_edit', account['email'], message='Please review and update your account information.') else: self.see_other('home') class Register(RequestHandler): "Register a new account account." KEYS = ['email', 'first_name', 'last_name', 'university', 'department', 'pi',