Commit 486605fa authored by Alex Constantin-Gómez's avatar Alex Constantin-Gómez
Browse files

Merge branch 'master' into 'flask-migrate'

Master

See merge request !1
parents b4a85368 bca53f25
Pipeline #211015 canceled with stage
in 5 seconds
...@@ -39,10 +39,11 @@ from models import * ...@@ -39,10 +39,11 @@ from models import *
# Register all blueprints/routes # Register all blueprints/routes
from blueprints import home_blueprint, persons_blueprint from blueprints import home_blueprint, persons_blueprint
# from blueprints.auth import auth_blueprint from blueprints.auth import auth_blueprint
app.register_blueprint(home_blueprint) app.register_blueprint(home_blueprint)
app.register_blueprint(persons_blueprint) app.register_blueprint(persons_blueprint)
# app.register_blueprint(auth_blueprint) app.register_blueprint(auth_blueprint)
# ===================== MIGRATION SETUP ===================== # ===================== MIGRATION SETUP =====================
APP_CONFIG_BINDINGS_DICT_KEY = "SQLALCHEMY_BINDS" APP_CONFIG_BINDINGS_DICT_KEY = "SQLALCHEMY_BINDS"
......
from flask import Blueprint, render_template, request, redirect, flash
from imperial_ldap.auth import ldap_login, ldap_logout
from config import url_for2
# Authentication (login) related routes
auth_blueprint = Blueprint("auth", __name__, url_prefix="/auth")
@auth_blueprint.route("/login", methods=["GET", "POST"])
def login():
if request.method == "GET":
return render_template("login.html")
# Handle post request
username = request.form.get("username")
password = request.form.get("password")
if username and password:
user = ldap_login(username, password)
if user:
# we're logged in
return redirect(url_for2("home.dashboard"))
else:
# bad credentials
flash("Invalid login credentials.")
return redirect(url_for2("auth.login"))
return "Please provide a username and password"
@auth_blueprint.route("/logout", methods=["GET"])
def logout():
ldap_logout() # Ignore this if using token-based authentication
return redirect(url_for2("home.index"))
from flask import Blueprint, render_template from flask import Blueprint, render_template, request
from config import url_for2
from imperial_ldap.auth import login_required
home_blueprint = Blueprint('home', __name__, url_prefix='/') home_blueprint = Blueprint('home', __name__, url_prefix='/')
@home_blueprint.route('') @home_blueprint.route('')
def home(): def index():
return render_template('index.html') return render_template('index.html')
@home_blueprint.route('/hello/<name>') @home_blueprint.route('/dashboard')
def hello(name: str): @login_required
return "Hello, " + name def dashboard(user):
return render_template('dashboard.html', user=user)
# Example route with database interaction:
# @home_blueprint.route('/entities', methods=['GET', 'POST'])
# @login_required
# def entities(user):
# if request.method == "GET":
# try:
# rows = ""
# for e in db.session.query(Entity).all():
# rows += str(e) + "<br>"
# return rows
# except:
# return "App database error"
# else:
# name = request.form.get('name')
# age = request.form.get('age')
# try:
# db.session.add(Entity(name=name, age=int(age)))
# db.session.commit()
# return redirect(url_for2('.entities'))
# except:
# return "Could not add entity."
...@@ -3,8 +3,9 @@ from utils.debug_utils import DebugUtils ...@@ -3,8 +3,9 @@ from utils.debug_utils import DebugUtils
# This should match exactly the name of the app you specified # This should match exactly the name of the app you specified
APP_NAME = "MY_APP_NAME_HERE" APP_NAME = "MY_APP_NAME_HERE"
# default mode is "dev" if environment variable doesn't have an assigned value
DEFAULT_MODE = "dev" # default mode is "prod" if environment variable doesn't have an assigned value
DEFAULT_MODE = "prod"
ENV = os.environ.get('ENV', DEFAULT_MODE).lower() ENV = os.environ.get('ENV', DEFAULT_MODE).lower()
DEBUG_MODE = ENV != 'prod' DEBUG_MODE = ENV != 'prod'
URL_PREFIX = f"/{APP_NAME}" if not DEBUG_MODE else "" URL_PREFIX = f"/{APP_NAME}" if not DEBUG_MODE else ""
...@@ -99,6 +100,10 @@ def get_app_config(): ...@@ -99,6 +100,10 @@ def get_app_config():
class Config(object): class Config(object):
APP_NAME = APP_NAME
URL_PREFIX = URL_PREFIX
SECRET_KEY = "my secret key"
SESSION_COOKIE_SECURE = True
DEBUG = False DEBUG = False
TESTING = False TESTING = False
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False
...@@ -107,10 +112,10 @@ class Config(object): ...@@ -107,10 +112,10 @@ class Config(object):
# Flask App settings for production environment # Flask App settings for production environment
class ProductionConfig(Config): class ProductionConfig(Config):
SECRET_KEY = "my secret key" # need to set this to something secure
PREFERRED_URL_SCHEME = 'https' PREFERRED_URL_SCHEME = 'https'
DEBUG = False DEBUG = False
APPLICATION_ROOT = f"/{APP_NAME}" APPLICATION_ROOT = f"/{APP_NAME}"
# Source: https://flask-sqlalchemy.palletsprojects.com/en/2.x/binds/
SQLALCHEMY_BINDS = PROD_BINDINGS SQLALCHEMY_BINDS = PROD_BINDINGS
......
html,
body {
height: 100%;
}
body {
display: -ms-flexbox;
display: -webkit-box;
display: flex;
-ms-flex-align: center;
-ms-flex-pack: center;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
padding-top: 40px;
padding-bottom: 40px;
background-color: #f5f5f5;
}
.form-signin {
width: 100%;
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-signin .checkbox {
font-weight: 400;
}
.form-signin .form-control {
position: relative;
box-sizing: border-box;
height: auto;
padding: 10px;
font-size: 16px;
}
.form-signin .form-control:focus {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
<!doctype html>
<html>
<head>
{% block head %}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous">
<title>{% block title %}{% endblock %}</title>
{% endblock %}
</head>
<body>
<div id="content">
<!-- Flashed alerts go here -->
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<strong>{{ message }}</strong> Please try again with your Imperial username and password.
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<!-- Body of the web page goes here -->
{% block content %}{% endblock %}
</div>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" crossorigin="anonymous"></script>
</body>
</html>
\ No newline at end of file
{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{{ url('home.index') }}">My Web App</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-item nav-link" href="{{ url('home.index') }}">Home <span class="sr-only">(current)</span></a>
<a class="nav-item nav-link active" href="{{ url('home.dashboard') }}">Dashboard</a>
<a class="nav-item nav-link" href="{{ url('auth.logout') }}">Logout</a>
</div>
</div>
</nav>
<h1>My Dashboard</h1>
<h3>Welcome back, {{ user.name }} {{ user.surname }}!</h3>
{% endblock %}
\ No newline at end of file
<!DOCTYPE html> {% extends "base.html" %}
<html lang="en">
<head> {% block title %}Home{% endblock %}
<title>Flask Template</title>
<meta charset="UTF-8"> {% block content %}
<meta name="viewport" content="width=device-width, initial-scale=1">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
</head> <a class="navbar-brand" href="{{ url('home.index') }}">My Web App</a>
<body> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<h1 id="title">Imperial PaaS - Python Flask Template</h1> <span class="navbar-toggler-icon"></span>
<nav> </button>
<ul> <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<li><a href="{{ url('home.home') }}">HOME</a></li> <div class="navbar-nav">
</ul> <a class="nav-item nav-link active" href="{{ url('home.index') }}">Home <span class="sr-only">(current)</span></a>
</nav> <a class="nav-item nav-link" href="{{ url('home.dashboard') }}">Dashboard</a>
</div>
<img src="{{ url('static', filename='img/python-logo.png') }}" width="100px" alt="python logo"/> </div>
</nav>
<h2>What is Flask Template</h2>
<p> <h1>Imperial PaaS - Python Flask Template</h1>
Flask Template is a simple web app programmed in Python-3 using flask micro-framework. It is created for begginers to understand the basics of creating a flask web app and deploying it on the Heroku. It can also be used as a template to create your new flask web apps.
</p><br> <img src="{{ url('static', filename='img/python-logo.png') }}" width="100px" alt="python logo"/>
<h3>Example CRUD form - Create a record in the database:</h3> <p>Python Flask template with Login</p><br>
<form method="post" action="{{ url('persons.create_person') }}">
Firstname:<br> <a href="{{ url('auth.login') }}">LOGIN HERE</a>
<input type="text" name="firstname">
<br>
Surname:<br> {% endblock %}
<input type="text" name="surname"> \ No newline at end of file
<br>
Age:<br>
<input type="number" name="age">
<br>
<button type="submit">Create Entry</button>
</form>
<br>
<a href="{{ url('persons.display_all_persons') }}">View records</a>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html> {% extends "base.html" %}
<html lang="en">
<head> {% block title %}Login{% endblock %}
<title>Flask Template</title>
<meta charset="UTF-8"> {% block head %}
<meta name="viewport" content="width=device-width, initial-scale=1"> {{ super() }}
</head> <link rel="stylesheet" href="{{ url('static', filename='css/login.css') }}">
<body>
<h1 id="title">Imperial PaaS - Python Flask Template</h1> {% endblock %}
<nav>
<ul>
<li><a href="{{ url('home.home') }}">HOME</a></li> {% block content %}
</ul>
</nav> <div class="text-center">
<form class="form-signin" method="post">
<form method="post"> <img class="mb-4" src="{{ url('static', filename='img/imperial-logo.png') }}" alt="" width="72" height="72">
LDAP Username:<br> <h1 class="h3 mb-3 font-weight-normal">Imperial LDAP Login</h1>
<input type="text" name="username">
<br> <label for="inputUsername" class="sr-only">LDAP Username</label>
Password:<br> <input type="text" name="username" id="inputUsername" class="form-control" placeholder="Username" required="" autofocus="">
<input type="password" name="password">
<br> <label for="inputPassword" class="sr-only">Password</label>
<button type="submit">Login</button> <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required="">
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form> </form>
</body> </div>
</html>
\ No newline at end of file {% endblock %}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment