def process_reset_request(token, form): if not valid_token(token): return page(load_content('expired.md')) tokens = get_tokens() rec = tokens.first(token=token) if rec: user = context.site.users.first(email=rec.email) if user: filler = dict( username=user.username, first_name=user.first_name, ) if context.user.is_admin: form.update( dict( new_password='******', confirm='somenewpassword', ) ) content = load_content('reset.md', **filler) + form.edit() return page(content) else: # no user by that email! error('invalid request') return redirect_to('/') else: error('invalid reset request') return redirect_to('/')
def delete_image(self, key, name): """Delete an image field""" record = locate(self.collection, key) if record: del record[name] record.save() return redirect_to(zoom.helpers.url_for(record.url, 'edit'))
def create_button(self, *args, **data): """Create a record""" collection = self.collection user = collection.user if collection.fields.validate(data): record = collection.model( collection.fields, ) record.pop('key', None) try: key = record.key except AttributeError: key = None if key and locate(collection, record.key) is not None: error('That {} already exists'.format(collection.item_name)) else: try: # convert property to data attribute # so it gets stored as data record.key = record.key except AttributeError: # can happen when key depends on database # auto-increment value. pass record.update(dict( created=now(), updated=now(), owner_id=user._id, created_by=user._id, updated_by=user._id, )) self.before_insert(record) collection.store.put(record) collection.search_engine(collection).add( record._id, collection.fields.as_searchable(), ) self.after_insert(record) msg = '%s added %s %s' % ( user.link, collection.link, record.link ) logger = logging.getLogger(__name__) logger.info(msg) log_activity(msg) return redirect_to(collection.url)
def delete(self, key, confirm='yes'): c = self.collection c.user.authorize('delete', c) if confirm == 'no': record = locate(c, key) if record: c.user.authorize('delete', record) self.before_delete(record) c.store.delete(record) c.search_engine(c).delete( record._id, ) self.after_delete(record) msg = '%s deleted %s %s' % ( c.user.link, c.link, record.name ) logger = logging.getLogger(__name__) logger.info(msg) log_activity(msg) return redirect_to(c.url)
def random(self): for n in range(5): choice([ lambda: success('Success %s' % n), lambda: warning('Warning %s' % n), lambda: error('Error %s' % n), ])() return redirect_to('/sample/alerts')
def save_button(self, key, *a, **data): """Save a record""" collection = self.collection user = collection.user user.authorize('update', collection) if collection.fields.validate(data): record = locate(collection, key) if record: user.authorize('update', record) record.update(collection.fields) record.pop('key', None) if record.key != key and locate(collection, record.key): # record key should always be a str, even if the actual # record.id is being used as the key. error('That {} already exists'.format(collection.item_name)) else: record.updated = now() record.updated_by = user._id # convert property to data attribute # so it gets stored as data record.key = record.key self.before_update(record) collection.store.put(record) collection.search_engine(collection).update( record._id, collection.fields.as_searchable(), ) self.after_update(record) msg = '%s updated %s %s' % ( user.link, collection.link, record.link ) logger = logging.getLogger(__name__) logger.info(msg) log_activity(msg) if record.key != key: log_activity( '%s changed %s %s to %s' % ( user.link, collection.link, key, record.key ) ) return redirect_to(record.url)
def make_message(token): """create a message to send to the user""" reset_link = redirect_to('/forgot/reset?token=%s' % token).render(context.request).headers['Location'] filler = dict( site_name=context.site.title, reset_link=reset_link, ).get message = markdown( dzfill( load('activate.md'), filler, ) ) logger = logging.getLogger(__name__) logger.debug('password reset link: %s', reset_link) return message
def index(self, q='', *args, **kwargs): """collection landing page""" def matches(item, search_text): """match a search by field values""" terms = search_text and search_text.split() fields.update(item) v = repr(fields.display_value()).lower() return terms and not any(t.lower() not in v for t in terms) c = self.collection user = c.user fields = c.fields if c.request.route[-1:] == ['index']: return redirect_to('/' + '/'.join(c.request.route[:-1]), **kwargs) actions = user.can('create', c) and ['New'] or [] authorized = (i for i in c.store if user.can('read', i)) matching = (i for i in authorized if not q or matches(i, q)) filtered = c.filter and filter(c.filter, matching) or matching items = sorted(filtered, key=c.order) if q: msg = '%s searched %s with %r (%d found)' % (user.link, c.link, q, len(items)) log_activity(msg) if len(items) != 1: footer_name = c.title else: footer_name = c.item_name footer = '%s %s' % (len(items), footer_name.lower()) content = browse([c.model(i) for i in items], labels=c.labels, columns=c.columns, fields=c.fields, footer=footer) return page(content, title=c.title, actions=actions, search=q)
def login_button(self, **data): logger = logging.getLogger(__name__) logger.debug('login_button called') site = self.model.site username = data.get('username') password = data.get('password') remember_me = bool(data.get('remember_me')) if username and password: users = Users(site.db) user = users.first(username=username, status='A') if user: if user.login(self.model, password, remember_me): logger.info( 'user {!r} sucesfully logged in'.format(username)) return redirect_to('/') logger.debug('failed login attempt for user {!r}'.format(username)) error('incorrect username or password') elif username: error('password missing') else: error('username missing')
def generate_response(instance_path, start_time=None): """generate response to web request""" profiler = None debugging = True system_timer = SystemTimer(start_time) # capture stdout real_stdout = sys.stdout sys.stdout = StringIO.StringIO() try: try: # initialize context system.setup(instance_path, request.server, system_timer) system_timer.add('system initializated') user.setup() system_timer.add('user initializated') manager.setup() system_timer.add('manager initializated') if user.is_disabled: # we know who the user is, and their account is disabled msg = 'User {user.link} is disabled' raise UnauthorizedException(msg.format(user=user)) debugging = (system.debugging or system.show_errors or user.is_developer or user.is_administrator) session = system.session if system.track_visits: visited(request.subject, session.sid) csrf_token = data.pop('csrf_token', None) if request.method == 'POST' and system.csrf_validation: if csrf_token == session.csrf_token: del session.csrf_token else: msg = 'expected:%s got:%s' % ( session.csrf_token, csrf_token) raise CrossSiteRequestForgeryAttempt(msg) requested_app_name = manager.requested_app_name() default_app_name = manager.default_app_name() os.chdir(system.config.sites_path) if not request.route: request.route.append(default_app_name) for app in manager.apps.values(): app.initialize(request) if manager.can_run(requested_app_name): system.app = manager.get_app(requested_app_name) profiler = (system.profile or user.profile) \ and cProfile.Profile() if profiler: profiler.enable() system_timer.add('app ready') response = system.app.run(request) system_timer.add('app returned') if profiler: profiler.disable() elif manager.can_run_if_login(requested_app_name): # as it stands now, an attacker can generate a list of # enabled apps by iterating the/a namespace and seeing # which ones return a logon form. def referrer(): """get the referrer""" uri = urllib.urlencode(dict(referrer=request.uri)) return uri and "?{}".format(uri) or '' response = redirect_to('/login{}'.format(referrer())) elif not requested_app_name: app = manager.get_app(default_app_name) if app: system.app = app else: raise Exception(default_app_name + ' app missing') response = system.app.run(request) elif manager.can_run(default_app_name): response = redirect_to('/') else: response = Page(PAGE_MISSING_MESSAGE).render() response.status = '404' timeout = session.save_session() set_session_cookie( response, session.sid, request.subject, timeout, system.secure_cookies, ) except UnauthorizedException: logger.security('unauthorized access attempt') if debugging: raise else: response = Page(UNAUTHORIZED_MESSAGE).render() response.status = '403' except CrossSiteRequestForgeryAttempt: logger.security('cross site forgery attempt') if debugging: raise else: response = redirect_to('/') except SessionExpiredException: response = Page(load_template( 'system_application_session_expired', SESSION_EXPIRED_MESSAGE)).render() except: t = htmlquote(traceback.format_exc()) logger.error(t) if debugging: try: tpl = load_template( 'system_application_error_developer', STANDARD_ERROR_MESSAGE) msg = tpl % dict(message=t) except: msg = SYSTEM_ERROR_MESSAGE % dict(message=t) else: try: msg = load_template( 'system_application_error_user', FRIENDLY_ERROR_MESSAGE ) except: msg = FRIENDLY_ERROR_MESSAGE try: response = Page(msg).render() except: response = HTMLResponse(msg) if profiler: stats_s = StringIO.StringIO() sortby = 'cumulative' ps = pstats.Stats(profiler, stream=stats_s) ps.sort_stats(sortby) ps.print_stats(.1) t = stats_s.getvalue() t = t.replace( system.lib_path, '~zoom' ).replace( '/usr/lib/python2.7/dist-packages/', '~' ).replace( '/usr/local/lib/python2.7/dist-packages/', '~' ) print(''.join([ '\n\n System Performance Metrics\n ' + '=' * 30, system_timer.report(), system.database.report(), system.db.report(), ' Profiler\n ------------\n', t ])) finally: printed_output = sys.stdout.getvalue() sys.stdout.close() sys.stdout = real_stdout logger.complete() system.release() if hasattr(response, 'printed_output'): response.printed_output = printed_output.replace( '<', '<' ).replace( '>', '>' ) return response
def warning(self): warning('that was close!') return redirect_to('/sample/alerts')
def clear(self): """Clear the search""" return redirect_to('/' + '/'.join(self.collection.request.route[:-1]))
def index(self, q='', *args, **kwargs): """collection landing page""" def get_recent(number): cmd = """ select row_id, max(value) as newest from attributes where kind = %s and attribute in ("created", "updated") group by row_id order by newest desc limit %s """ ids = [id for id, _ in c.store.db(cmd, c.store.kind, number)] return c.store.get(ids) c = self.collection user = c.user if c.request.route[-1:] == ['index']: return redirect_to('/'+'/'.join(c.request.route[:-1]), **kwargs) actions = user.can('create', c) and ['New'] or [] logger = logging.getLogger(__name__) if q: title = 'Selected ' + c.title records = c.search_engine(c).search(q) else: many_records = bool(len(c.store) > 50) logger.debug('many records: %r', many_records) if many_records and not kwargs.get('all'): title = 'Most Recently Updated ' + c.title records = get_recent(15) actions.append(('Show All', 'clients?all=1')) else: title = c.title records = c.store authorized = (i for i in records if user.can('read', i)) filtered = c.filter and filter(c.filter, authorized) or authorized items = sorted(filtered, key=c.order) num_items = len(items) if num_items != 1: footer_name = c.title.lower() else: footer_name = c.item_title.lower() if q: msg = '%s searched %s with %r (%d found)' % ( user.link, c.link, q, num_items ) log_activity(msg) footer = '{:,} {} found in search of {:,} {}'.format( num_items, footer_name, len(c.store), c.title.lower(), ) else: if many_records: footer = '{:,} {} shown of {:,} {}'.format( num_items, footer_name, len(c.store), c.title.lower(), ) else: footer = '%s %s' % (len(items), footer_name) content = browse( [c.model(i) for i in items], labels=c.get_labels(), columns=c.get_columns(), fields=c.fields, footer=footer ) return page(content, title=title, actions=actions, search=q)
def error(self): error('that was bad!') return redirect_to('/sample/alerts')
def index(self, q='', *args, **kwargs): """collection landing page""" c = self.collection user = c.user if c.request.route[-1:] == ['index']: return redirect_to('/' + '/'.join(c.request.route[:-1]), **kwargs) actions = user.can('create', c) and ['New'] or [] logger = logging.getLogger(__name__) if q: title = 'Selected ' + c.title records = c.search(q) else: has_many_records = c.has_many_records logger.debug('has many records: %r', has_many_records) if has_many_records and not kwargs.get('all'): title = 'Most Recently Updated ' + c.title records = self._get_recent(15) actions.append(('Show All', c.url + '?all=1')) else: title = c.title records = c.store authorized = (i for i in records if user.can('read', i)) filtered = c.filter and filter(c.filter, authorized) or authorized items = sorted(filtered, key=c.order) items = c.sorter and c.sorter(items) or items num_items = len(items) if num_items != 1: footer_name = c.title.lower() else: footer_name = c.item_title.lower() if q: msg = '%s searched %s with %r (%d found)' % (user.link, c.link, q, num_items) log_activity(msg) footer = '{:,} {} found in search of {:,} {}'.format( num_items, footer_name, len(c.store), c.title.lower(), ) else: if has_many_records: footer = '{:,} {} shown of {:,} {}'.format( num_items, footer_name, len(c.store), c.title.lower(), ) else: footer = '%s %s' % (len(items), footer_name) content = browse([c.model(i) for i in items], labels=c.get_labels(), columns=c.get_columns(), fields=c.fields, footer=footer) return page(content, title=title, actions=actions, search=q)
def generate_response(instance_path, start_time=None): """generate response to web request""" profiler = None debugging = True system_timer = SystemTimer(start_time) # capture stdout real_stdout = sys.stdout sys.stdout = StringIO.StringIO() try: try: # initialize context system.setup(instance_path, request.server, system_timer) system_timer.add('system initializated') user.setup() system_timer.add('user initializated') manager.setup() system_timer.add('manager initializated') if user.is_disabled: # we know who the user is, and their account is disabled msg = 'User {user.link} is disabled' raise UnauthorizedException(msg.format(user=user)) debugging = (system.debugging or system.show_errors or user.is_developer or user.is_administrator) session = system.session if system.track_visits: visited(request.subject, session.sid) csrf_token = data.pop('csrf_token', None) if request.method == 'POST' and system.csrf_validation: if csrf_token == session.csrf_token: del session.csrf_token else: msg = 'expected:%s got:%s' % (session.csrf_token, csrf_token) raise CrossSiteRequestForgeryAttempt(msg) requested_app_name = manager.requested_app_name() default_app_name = manager.default_app_name() os.chdir(system.config.sites_path) if not request.route: request.route.append(default_app_name) for app in manager.apps.values(): app.initialize(request) if manager.can_run(requested_app_name): system.app = manager.get_app(requested_app_name) profiler = (system.profile or user.profile) \ and cProfile.Profile() if profiler: profiler.enable() system_timer.add('app ready') response = system.app.run(request) system_timer.add('app returned') if profiler: profiler.disable() elif manager.can_run_if_login(requested_app_name): # as it stands now, an attacker can generate a list of # enabled apps by iterating the/a namespace and seeing # which ones return a logon form. def referrer(): """get the referrer""" uri = urllib.urlencode(dict(referrer=request.uri)) return uri and "?{}".format(uri) or '' response = redirect_to('/login{}'.format(referrer())) elif not requested_app_name: app = manager.get_app(default_app_name) if app: system.app = app else: raise Exception(default_app_name + ' app missing') response = system.app.run(request) elif manager.can_run(default_app_name): response = redirect_to('/') else: response = Page(PAGE_MISSING_MESSAGE).render() response.status = '404' timeout = session.save_session() set_session_cookie( response, session.sid, request.subject, timeout, system.secure_cookies, ) except UnauthorizedException: logger.security('unauthorized access attempt') if debugging: raise else: response = Page(UNAUTHORIZED_MESSAGE).render() response.status = '403' except CrossSiteRequestForgeryAttempt: logger.security('cross site forgery attempt') if debugging: raise else: response = redirect_to('/') except SessionExpiredException: response = Page( load_template('system_application_session_expired', SESSION_EXPIRED_MESSAGE)).render() except: t = htmlquote(traceback.format_exc()) logger.error(t) if debugging: try: tpl = load_template('system_application_error_developer', STANDARD_ERROR_MESSAGE) msg = tpl % dict(message=t) except: msg = SYSTEM_ERROR_MESSAGE % dict(message=t) else: try: msg = load_template('system_application_error_user', FRIENDLY_ERROR_MESSAGE) except: msg = FRIENDLY_ERROR_MESSAGE try: response = Page(msg).render() except: response = HTMLResponse(msg) if profiler: stats_s = StringIO.StringIO() sortby = 'cumulative' ps = pstats.Stats(profiler, stream=stats_s) ps.sort_stats(sortby) ps.print_stats(.1) t = stats_s.getvalue() t = t.replace(system.lib_path, '~zoom').replace( '/usr/lib/python2.7/dist-packages/', '~').replace('/usr/local/lib/python2.7/dist-packages/', '~') print(''.join([ '\n\n System Performance Metrics\n ' + '=' * 30, system_timer.report(), system.database.report(), system.db.report(), ' Profiler\n ------------\n', t ])) finally: printed_output = sys.stdout.getvalue() sys.stdout.close() sys.stdout = real_stdout logger.complete() system.release() if hasattr(response, 'printed_output'): response.printed_output = printed_output.replace('<', '<').replace( '>', '>') return response
def success(self): success('that was great!') return redirect_to('/sample/alerts')