Skip to content
Snippets Groups Projects
Commit 310d4ef7 authored by arwunder's avatar arwunder
Browse files

Merge branch 'add-acess-only-for-registered-users-+-logout' into 'main'

Add acess only for registered users + logout

See merge request !25
parents 41bc68d4 0dc5c038
No related branches found
No related tags found
1 merge request!25Add acess only for registered users + logout
Pipeline #14787 passed
......@@ -4,6 +4,7 @@ importlib-metadata
# Framework and libraries
flask==2.2.2
python-dotenv
flask-login
flask-mongoengine==1.0
Pillow
......
......@@ -7,6 +7,7 @@ Flask tutorial: https://flask.palletsprojects.com/en/2.2.x/tutorial/
"""
import logging
from os import environ
import os
from typing import Dict, Optional
......@@ -23,6 +24,7 @@ from .utils import get_version
from .db import init_db
from .logging import init_logging
logger = logging.getLogger(__name__)
def create_app(config: Optional[Dict] = None) -> Flask:
"""
......@@ -39,7 +41,6 @@ def create_app(config: Optional[Dict] = None) -> Flask:
init_logging(flask_app)
# load the instance config, if it exists, when not testing
if config is None:
flask_app.config.from_pyfile('config.py', silent=True)
......@@ -67,9 +68,9 @@ def create_app(config: Optional[Dict] = None) -> Flask:
def hello():
return 'Hello, World!'
from . import auth
flask_app.register_blueprint(auth.bp)
from .auth import init_auth
init_auth(flask_app)
return flask_app
......@@ -89,8 +90,18 @@ def server_info() -> Response:
This is useful for monitoring the server, and for checking that the server is
running correctly.
"""
# Test for database connection
database_ping = False
try:
from .db import db # pylint: disable=import-outside-toplevel
database_ping = db.connection.admin.command('ping').get("ok", False) and True
except Exception as exc: # pylint: disable=broad-except
logger.warning("Error querying mongodb server: %r", exc,
exc_info=True,
extra=flask_app.config.get_namespace("MONGODB"))
response = {
"database_connectable": database_ping,
"version": get_version(),
"build_date": environ.get("BUILD_DATE", None)
}
......
import functools
import logging
from flask import (
Blueprint, flash, g, redirect, render_template, request, session, url_for
Blueprint, flash, redirect, render_template, request, session, url_for
)
from flask_login import (
LoginManager,
login_user,
logout_user,
login_required,
current_user,
)
from werkzeug.security import check_password_hash, generate_password_hash
from sentry_sdk import set_user
from .models import User
from mongoengine import DoesNotExist
bp = Blueprint('auth', __name__, url_prefix='/auth')
logger = logging.getLogger(__name__)
@bp.before_app_request
def load_logged_in_user():
def init_auth(app):
"""
If a user id is stored in the session, load the user object from
Integrate authentication into the application.
"""
app.register_blueprint(bp)
user_id = session.get('user_id')
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.user_loader(load_logged_in_user)
if user_id is None:
g.user = None
else:
g.user = User.objects.get(id=user_id)
login_manager.init_app(app)
logger.debug("Initialized authentication")
def login_required(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
return redirect(url_for('auth.login'))
return view(**kwargs)
def load_logged_in_user(user_id):
"""
Load a user from the database, given the user's id.
"""
try:
user = User.objects.get(id=user_id)
set_user({"id": str(user.id), "email": user.email})
except DoesNotExist:
logger.error("User not found: %s", user_id)
return None
return wrapped_view
return user
@bp.route('/register', methods=('GET', 'POST'))
......@@ -93,12 +109,35 @@ def login():
error = 'Incorrect password.'
if error is None:
session.clear()
session['user_id'] = str(user['id'])
flash(f"Hello {email}, You have been logged in.")
return redirect(url_for('views.list_bid'))
remember_me = bool(request.form.get("remember-me", False))
if login_user(user, remember=remember_me):
flash(f"Hello {email}, You have been logged in.")
next = request.args.get('next')
# Better check that the user actually clicked on a relative link
# or else they could redirect you to a malicious website!
if next is None or not next.startswith('/'):
next = url_for('views.index')
print("Error logging in:", error)
return redirect(next)
else:
error = "Error logging in."
logger.info("Error logging user in: %r: Error: %s", email, error)
flash(error)
return render_template('auth/login.html')
@bp.route('/logout')
@login_required
def logout():
"""
Log out the current user.
Also removes the "remember me" cookie.
"""
logout_user()
flash("You have been logged out.")
return redirect(url_for('views.index'))
......@@ -8,10 +8,12 @@ from mongoengine import (
DateTimeField,
EmailField,
FileField,
BooleanField,
)
from flask_login import UserMixin
class User(db.Document):
class User(UserMixin, db.Document):
"""
Model representing a user of the auction site.
"""
......@@ -22,6 +24,26 @@ class User(db.Document):
created_at = DateTimeField(required=True, default=datetime.utcnow)
is_disabled = BooleanField(default=False)
"Whether the user is disabled."
@property
def is_active(self) -> bool:
"""
Return whether the user is active.
This is used by Flask-Login to determine whether the user is
allowed to log in.
"""
return not self.is_disabled
def get_id(self) -> str:
"""
Return the user's id as a string.
"""
return str(self.id)
class Item(db.Document):
"""
......
......@@ -5,8 +5,9 @@ Basic views for Application
import random
from datetime import datetime, timedelta
from flask import Blueprint, render_template, send_from_directory, request, flash, url_for, redirect
from flask import Blueprint, flash, redirect, render_template, request, url_for
from .models import Item, User
from .auth import login_required, current_user
# Main blueprint.
bp = Blueprint('views', __name__)
......@@ -31,7 +32,6 @@ def test_item_adding():
"""
Test item is added
"""
# for test purpose create random number (unique mail address required)
ran_int = str(random.randint(0,10000))
......@@ -52,6 +52,7 @@ def test_item_adding():
return "OK"
@bp.route("/addItem", methods=('GET', 'POST'))
@login_required
def add_item():
"""
AddItem page.
......@@ -100,6 +101,7 @@ def add_item():
@bp.route("/listBid")
@login_required
def list_bid():
"""
page that lists all items currently on auction
......@@ -114,6 +116,7 @@ def list_bid():
return html
@bp.route("/bid")
@login_required
def bid(id):
"""
method that saves bid on object
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment