Pastebin
Paste #24101: No description
< previous paste - next paste>
Pasted by Anonymous Coward
### models.py from sqlalchemy.dialects.postgresql import UUID import uuid from datetime import datetime from hashlib import md5 from app import db, login from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) password_hash = db.Column(db.String(128)) posts = db.relationship('Post', backref='author', lazy='dynamic') about_me = db.Column(db.String(140)) last_seen = db.Column(db.DateTime, default=datetime.utcnow) is_deleted = db.Column(db.Boolean, default=False) def __repr__(self): return '<User {}>'.format(self.username) def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) def avatar(self, size): digest = md5(self.username.encode('utf-8')).hexdigest() return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format( digest, size) @login.user_loader def load_user(id): return User.query.get(int(id)) class Post(db.Model): id = db.Column(db.Integer, primary_key=True) body = db.Column(db.String(140)) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) def __repr__(self): return '<Post {}>'.format(self.body) class ChallengeCategory(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String) description = db.Column(db.String) date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) is_deleted = db.Column(db.Boolean, default=False) challenges = db.relationship('Challenge', backref='category_challenge', lazy='dynamic') def __repr__(self): return f'<ChallengeCategory {self.name}>' class ChallengeLevel(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, unique=True) description = db.Column(db.String) sort_key = db.Column(db.Integer) date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) is_deleted = db.Column(db.Boolean, default=False) challenges = db.relationship('Challenge', backref='level_challenge', lazy='dynamic') def __repr__(self): return f'<ChallengeLevel {self.name}>' class Challenge(db.Model): id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) is_deleted = db.Column(db.Boolean, default=False) is_published = db.Column(db.Boolean, default=False) name = db.Column(db.String) instructions = db.Column(db.String) hint = db.Column(db.String) flag_hash = db.Column(db.String(128)) category_id = db.Column(db.Integer, db.ForeignKey('challenge_category.id')) level_id = db.Column(db.Integer, db.ForeignKey('challenge_level.id')) score = db.Column(db.Integer, default=0) def set_flag(self, flag): self.flag_hash = generate_password_hash(flag) def check_flag(self, flag): return check_password_hash(self.flag_hash, flag) def __repr__(self): return f'<Challenge {self.name}>' ### routes.py from datetime import datetime from flask import render_template, flash, redirect, url_for, request from flask_login import login_user, logout_user, current_user, login_required from werkzeug.urls import url_parse from app import app, db from app.forms import LoginForm, RegistrationForm, EditProfileForm from app.models import User, Challenge @app.before_request def before_request(): if current_user.is_authenticated: current_user.last_seen = datetime.utcnow() db.session.commit() @app.route('/') @app.route('/index') @login_required def index(): posts = [ { 'author': {'username': 'John'}, 'body': 'Beautiful day in Portland!' }, { 'author': {'username': 'Susan'}, 'body': 'The Avengers movie was so cool!' } ] return render_template('index.html', title='Home', posts=posts) @app.route('/login', methods=['GET', 'POST']) def login(): if current_user.is_authenticated: return redirect(url_for('index')) form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.username.data).first() if user is None or not user.check_password(form.password.data): flash('Invalid username or password') return redirect(url_for('login')) login_user(user, remember=form.remember_me.data) next_page = request.args.get('next') if not next_page or url_parse(next_page).netloc != '': next_page = url_for('index') return redirect(next_page) return render_template('login.html', title='Sign In', form=form) @app.route('/logout') def logout(): logout_user() return redirect(url_for('index')) @app.route('/register', methods=['GET', 'POST']) def register(): if current_user.is_authenticated: return redirect(url_for('index')) form = RegistrationForm() if form.validate_on_submit(): user = User(username=form.username.data, email=form.email.data) user.set_password(form.password.data) db.session.add(user) db.session.commit() flash('Congratulations, you are now a registered user!') return redirect(url_for('login')) return render_template('register.html', title='Register', form=form) @app.route('/user/<username>') @login_required def user(username): user = User.query.filter_by(username=username).first_or_404() posts = [ {'author': user, 'body': 'Test post #1'}, {'author': user, 'body': 'Test post #2'} ] return render_template('user.html', user=user, posts=posts) @app.route('/edit_profile', methods=['GET', 'POST']) @login_required def edit_profile(): form = EditProfileForm(current_user.username) if form.validate_on_submit(): current_user.username = form.username.data current_user.about_me = form.about_me.data db.session.commit() flash('Your changes have been saved.') return redirect(url_for('edit_profile')) elif request.method == 'GET': form.username.data = current_user.username form.about_me.data = current_user.about_me return render_template('edit_profile.html', title='Edit Profile', form=form) @app.route('/challenges') @login_required def challenges(): #challenges = Challenge.order_by(Challenge.score.asc()).all() #challenges = [] published_challenges = Challenge.query.filter_by(is_deleted=False, is_published=True)(Challenge.score.asc()) return render_template('challenges.html', title='Challenges', user=user, challenges=published_challenges) ################### #This line fails: # published_challenges = Challenge.query.filter_by(is_deleted=False, is_published=True)(Challenge.score.asc()) ### Full error FLASK_APP = app.py FLASK_ENV = development FLASK_DEBUG = 0 In folder C:/wc/sascode/python/CTF C:\wc\sascode\python\CTF\venv\Scripts\python.exe -m flask run [2022-10-29 20:39:10,488] INFO in __init__: ctfwebapp startup * Serving Flask app 'app.py' * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:5000 Press CTRL+C to quit [2022-10-29 20:42:47,940] ERROR in app: Exception on /challenges [GET] Traceback (most recent call last): File "C:\wc\sascode\python\CTF\venv\lib\site-packages\flask\app.py", line 2525, in wsgi_app response = self.full_dispatch_request() File "C:\wc\sascode\python\CTF\venv\lib\site-packages\flask\app.py", line 1822, in full_dispatch_request rv = self.handle_user_exception(e) File "C:\wc\sascode\python\CTF\venv\lib\site-packages\flask\app.py", line 1820, in full_dispatch_request rv = self.dispatch_request() File "C:\wc\sascode\python\CTF\venv\lib\site-packages\flask\app.py", line 1796, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) File "C:\wc\sascode\python\CTF\venv\lib\site-packages\flask_login\utils.py", line 290, in decorated_view return current_app.ensure_sync(func)(*args, **kwargs) File "C:\wc\sascode\python\CTF\app\routes.py", line 105, in challenges published_challenges = Challenge.query.filter_by(is_deleted=False, is_published=True)(Challenge.score.asc()) TypeError: 'Query' object is not callable 127.0.0.1 - - [29/Oct/2022 20:42:48] "GET /challenges?username=sdktda HTTP/1.1" 500 - 127.0.0.1 - - [29/Oct/2022 20:42:48] "GET /static/bootstrap-5.2.2-dist/css/bootstrap.min.css HTTP/1.1" 200 - 127.0.0.1 - - [29/Oct/2022 20:42:48] "GET /static/bootstrap-5.2.2-dist/js/bootstrap.bundle.min.js HTTP/1.1" 200 - 127.0.0.1 - - [29/Oct/2022 20:42:48] "GET /static/css/style.css HTTP/1.1" 200 - 127.0.0.1 - - [29/Oct/2022 20:42:48] "GET /static/images/logo.png HTTP/1.1" 200 -
New Paste
Go to most recent paste.