def test_get_all_entity_classes(self): classes = all_entity_classes() assert Message in classes assert PrivateMessage in classes
def get(self): LIMIT = 30 base_audit_q = AuditEntry.query base_security_q = SecurityAudit.query before = request.args.get("before") after = request.args.get("after") # filter on user filter_user = None user_id = request.args.get("user") if user_id: user_id = int(user_id) filter_user = User.query.get(user_id) base_audit_q = base_audit_q.filter(AuditEntry.user == filter_user) base_security_q = base_security_q.filter( SecurityAudit.manager == filter_user ) # filter by types all_classes = sorted(all_entity_classes(), key=lambda c: c.__name__) all_types = {e.entity_type for e in all_classes} filter_types = set(request.args.getlist("types")) & all_types if filter_types: if len(filter_types) == 1: t = list(filter_types)[0] audit_expr = AuditEntry.entity_type == t sec_expr = sa.sql.or_( SecurityAudit.object == None, Entity._entity_type == t ) else: audit_expr = AuditEntry.entity_type.in_(filter_types) sec_expr = sa.sql.or_( SecurityAudit.object == None, Entity._entity_type.in_(filter_types) ) base_audit_q = base_audit_q.filter(audit_expr) base_security_q = ( base_security_q.join(SecurityAudit.object) .filter(sec_expr) .reset_joinpoint() ) def after_query(q, model, date): return q.filter(model.happened_at > date).order_by(model.happened_at.asc()) def before_query(q, model, date): return q.filter(model.happened_at < date).order_by(model.happened_at.desc()) if after: after = datetime.strptime(after, "%Y-%m-%dT%H:%M:%S.%f") audit_q = after_query(base_audit_q, AuditEntry, after) security_q = after_query(base_security_q, SecurityAudit, after) else: before = ( datetime.strptime(before, "%Y-%m-%dT%H:%M:%S.%f") if before else datetime.utcnow() ) audit_q = before_query(base_audit_q, AuditEntry, before) security_q = before_query(base_security_q, SecurityAudit, before) audit_entries = ( audit_q.options(sa.orm.joinedload(AuditEntry.entity)).limit(LIMIT).all() ) security_entries = ( security_q.options(sa.orm.joinedload(SecurityAudit.object)) .limit(LIMIT) .all() ) # audit_entries = [] all_entries = sorted( list( chain( # (AuditEntryPresenter(e) for e in audit_entries), # (SecurityEntryPresenter(e) for e in security_entries), ) ) ) if after: all_entries = all_entries[:LIMIT] else: all_entries = all_entries[-LIMIT:] all_entries.reverse() # event are presented from most to least recent # group entries by day entries = [] day_entries = None current_day = None for e in all_entries: e_date = e.date if e_date.date() != current_day: current_day = e_date.date() day_entries = [] entries.append((e_date.date(), day_entries)) day_entries.append(e) top_date = "" lowest_date = "" if entries: # top_date and lowest_date are converted to naive datetime (from UTC), so # that isoformat does not include TZ shift (else we should fix strptime # above) top_date = entries[0][1][0].date.astimezone(pytz.utc).replace(tzinfo=None) lowest_date = ( entries[-1][1][-1].date.astimezone(pytz.utc).replace(tzinfo=None) ) after_queries = ( after_query(base_audit_q, AuditEntry, top_date), after_query(base_security_q, SecurityAudit, top_date), ) before_queries = ( before_query(base_audit_q, AuditEntry, lowest_date), before_query(base_security_q, SecurityAudit, lowest_date).limit(1), ) if not any(q.limit(1).first() is not None for q in after_queries): top_date = "" else: top_date = top_date.isoformat() if not any(q.first() is not None for q in before_queries): lowest_date = "" else: lowest_date = lowest_date.isoformat() current_date = None if entries: current_date = format_date_for_input(entries[0][0]) # build prev/next urls url_params = {} if filter_user: url_params["user"] = filter_user.id if filter_types: url_params["types"] = list(filter_types)[0] ctx = { "entries": entries, "filter_user": filter_user, "all_classes": [(c.__name__, c.entity_type) for c in all_classes], "filter_types": filter_types, "url_params": url_params, "current_date": current_date, "top_date": top_date, "lowest_date": lowest_date, } return render_template("admin/audit.html", **ctx)
def get(self): LIMIT = 30 base_audit_q = AuditEntry.query base_security_q = SecurityAudit.query before = request.args.get('before') after = request.args.get('after') # filter on user filter_user = None user_id = request.args.get('user') if user_id: user_id = int(user_id) filter_user = User.query.get(user_id) base_audit_q = base_audit_q \ .filter(AuditEntry.user == filter_user) base_security_q = base_security_q \ .filter(SecurityAudit.manager == filter_user) # filter by types all_classes = sorted(all_entity_classes(), key=lambda c: c.__name__) all_types = {e.entity_type for e in all_classes} filter_types = set(request.args.getlist('types')) & all_types if filter_types: if len(filter_types) == 1: t = list(filter_types)[0] audit_expr = AuditEntry.entity_type == t sec_expr = sa.sql.or_( SecurityAudit.object == None, Entity._entity_type == t, ) else: audit_expr = AuditEntry.entity_type.in_(filter_types) sec_expr = sa.sql.or_( SecurityAudit.object == None, Entity._entity_type.in_(filter_types), ) base_audit_q = base_audit_q.filter(audit_expr) base_security_q = base_security_q \ .join(SecurityAudit.object) \ .filter(sec_expr) \ .reset_joinpoint() def after_query(q, model, date): return q \ .filter(model.happened_at > date) \ .order_by(model.happened_at.asc()) def before_query(q, model, date): return q \ .filter(model.happened_at < date) \ .order_by(model.happened_at.desc()) if after: after = datetime.strptime(after, '%Y-%m-%dT%H:%M:%S.%f') audit_q = after_query(base_audit_q, AuditEntry, after) security_q = after_query(base_security_q, SecurityAudit, after) else: before = (datetime.strptime(before, '%Y-%m-%dT%H:%M:%S.%f') if before else datetime.utcnow()) audit_q = before_query(base_audit_q, AuditEntry, before) security_q = before_query(base_security_q, SecurityAudit, before) audit_entries = audit_q \ .options(sa.orm.joinedload(AuditEntry.entity)) \ .limit(LIMIT) \ .all() security_entries = security_q \ .options(sa.orm.joinedload(SecurityAudit.object)) \ .limit(LIMIT) \ .all() # audit_entries = [] all_entries = sorted( list( chain( # (AuditEntryPresenter(e) for e in audit_entries), # (SecurityEntryPresenter(e) for e in security_entries), ), ), ) if after: all_entries = all_entries[:LIMIT] else: all_entries = all_entries[-LIMIT:] all_entries.reverse() # event are presented from most to least recent # group entries by day entries = [] day_entries = None current_day = None for e in all_entries: e_date = e.date if e_date.date() != current_day: current_day = e_date.date() day_entries = [] entries.append((e_date.date(), day_entries)) day_entries.append(e) top_date = '' lowest_date = '' if entries: # top_date and lowest_date are converted to naive datetime (from UTC), so # that isoformat does not include TZ shift (else we should fix strptime # above) top_date = entries[0][1][0].date.astimezone(pytz.utc).replace( tzinfo=None, ) lowest_date = entries[-1][1][-1].date \ .astimezone(pytz.utc) \ .replace(tzinfo=None) after_queries = ( after_query(base_audit_q, AuditEntry, top_date), after_query(base_security_q, SecurityAudit, top_date), ) before_queries = ( before_query(base_audit_q, AuditEntry, lowest_date), before_query( base_security_q, SecurityAudit, lowest_date, ).limit(1), ) if not any(q.limit(1).first() is not None for q in after_queries): top_date = '' else: top_date = top_date.isoformat() if not any(q.first() is not None for q in before_queries): lowest_date = '' else: lowest_date = lowest_date.isoformat() current_date = None if entries: current_date = format_date_for_input(entries[0][0]) # build prev/next urls url_params = {} if filter_user: url_params['user'] = filter_user.id if filter_types: url_params['types'] = list(filter_types)[0] ctx = { 'entries': entries, 'filter_user': filter_user, 'all_classes': [(c.__name__, c.entity_type) for c in all_classes], 'filter_types': filter_types, 'url_params': url_params, 'current_date': current_date, 'top_date': top_date, 'lowest_date': lowest_date, } return render_template("admin/audit.html", **ctx)