Using Flask-HTTPAuth when serving a static folder - flask

I'm using Flask to serve a static folder:
from flask import Flask, send_from_directory
from flask_httpauth import HTTPBasicAuth
app = Flask(__name__,
static_url_path='',
static_folder='html_files')
...
#app.route('/')
#auth.login_required
def send_html_files():
return send_from_directory('html_files', 'main.html')
I used the first example in Flask-HTTPAuth docs in order to add basic authentication to my website. Just a regular username and password is enough for me.
The problem is that the authentication dialog is not showing when the user go directly to http://localhost:5000/a/b/c (it works on http://localhost:5000/)
What is the proper way of doing this? On the other hand, what is the quick and dirty way?

#app.route('/') matches your root path only.
Try something like this to match every path:
#app.route('/<path:filename>')
#auth.login_required
def send_html_files(filename):
return send_from_directory('html_files', filename)

Related

Why is FLASK not running on given route?

I am not able to get http://127.0.0.1:5000/movie Url from the browser.
Every time it gives 404. The only time it worked was with URL from hello world.
I am trying to run a recommender system deployment solution with flask, based on https://medium.com/analytics-vidhya/build-a-movie-recommendation-flask-based-deployment-8e2970f1f5f1.
I have tried uninstall flask and install again but nothing seems to work.
Thank you!
from flask import Flask,request,jsonify
from flask_cors import CORS
import recommendation
app = Flask(__name__)
CORS(app)
#app.route('/movie', methods=['GET'])
def recommend_movies():
res = recommendation.results(request.args.get('title'))
return jsonify(res)
if __name__=='__main__':
app.run(port = 5000, debug = True)
http://127.0.0.1:5000/movie
be careful not writing '/' after movie like http://127.0.0.1:5000/movie/

FLASK, How to redirect Google autentication to a local html.file

Hi everyone I have implemented the Google Authentication with API.
I would like that once the user is authenticated the page redirect to a local html/Javascript application.
I am trying the following code which is not working because it is not finding the correct url.
from flask import Flask, redirect, url_for, session, request, render_template
from authlib.integrations.flask_client import OAuth
import os
from datetime import timedelta
# App config
app = Flask(__name__)
app.secret_key = "random secret"
# oAuth Setup
oauth = OAuth(app)
google = oauth.register(
name='google',
client_id='',
client_secret='',
access_token_url='https://accounts.google.com/o/oauth2/token',
access_token_params=None,
authorize_url='https://accounts.google.com/o/oauth2/auth',
authorize_params=None,
api_base_url='https://www.googleapis.com/oauth2/v1/',
client_kwargs={'scope': 'openid email profile'},
)
#app.route('/')
def hello_world():
email = dict(session).get('email',None)
return f'Hello, {email}!'
#app.route('/login')
def login():
google = oauth.create_client('google')
redirect_uri = url_for('authorize', _external=True)
return google.authorize_redirect(redirect_uri)
#app.route('/authorize')
def authorize():
google = oauth.create_client('google')
token = google.authorize_access_token()
resp = google.get('userinfo')
user_info = resp.json()
session['email'] = user_info['email']
return redirect('file:///home/luca/Desktop/ft_userdata/ProvaLogIn/prova.htm')
if __name__ == "__main__":
app.run(debug=True)
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
THe html that i am trying to render is simply an html local file with wrote hello
you need to create folder called templates inside your project in this folder you will add your html file in your case it will be prova.html
and change the return statement to
return render_template('prova.html')
this how should your directory tree should look like (general view)
├── app.py
├── static
└── templates
└── status.html
hope this solve your issue

How to redefine url_for in flask by automatically adding a string '/foo' as a prefix of the url generated from url_for?

It may look very odd, but this is what I want to achieve exactly, it is not related with blueprints or add prefix to all routers. thanks!
You can define your own:
# url_for_custom.py
import flask
def url_for(endpoint, **values):
url = flask.url_for(endpoint, **values)
if not values.get('_external', False):
url = '/foo' + url
return url
If you wish to change it globally, you can monkey-patch some time early on:
# __init__.py
import flask
from url_for_custom import url_for
flask.url_for = url_for
Although it's perhaps better to simply import and use your own implementation.

angular django rewrite unmatched urls to index.html (angular app)

I have a django server and an angular app.
I am able to launch the angular app and navigate to the various parts of the site using links i have added to the app.
But if I want to go to a part of the site directly I get a 404 error.
example if I have a link in my app that directs me to
niftysite.com/team
it works
but if I put in my browsers url
niftysite.com/team
it fails with 404
I understand this is because the default behavior is to look for the link to the page in the servers urls.
I also understand that the fix is to have server side 404s redirect to the angular index.html page with the route params included.
My question is how?
I have already started on an implementation but I am not sure how to fix it. Any guidance the rest of the way through would be helpful.
here is what I have so far.
urls.py
handler404 = views.error_404
views.py
from django.shortcuts import render
def error_404(request):
data = {}
return render(request, 'index.html', data)
similar to this question, but I am not using Nginx
How to redirect 404 requests to homepage in Django single page app using Nginx?
Here is the implementation:
urls.py
url(r'^.*$', views.PassToAngular.as_view())
make sure this url is the last url in your urls array.
views.py
from django.shortcuts import render
from django.views.generic import TemplateView
class PassToAngular(TemplateView):
def get(self, request, **kwargs):
return render(request, 'index.html', context= None)
thanks to MihirKavatkar for your help!

Apply common custom authentication functionality to multiple Flask projects

I've created a class which authenticates users based on our company's user server. I'd like to apply it to any of our Flask apps which use Flask-Login rather than repeating the code in each project. I'm not sure what the right pattern for this is, or how to implement it.
I thought of a few options:
Python module - simply authentication, the module would do the login then return something (maybe credentials or token).
Flask 'app' - authenticates, includes a login and logout screen, and somehow gets linked in with #login_manager.user_loader. The issue I see is that the user loaded could have any application's User schema.
What is a good pattern for implementing this common authentication for multiple projects?
Extract the common functions of setting up a Flask-Login manger and the custom login views/functions you need to a simple Flask extension package. Install this package with pip in the environment of each project and use it when creating that project's Flask app.
company_auth/company_auth.py
from flask import Blueprint, redirect, url_for, render_template
from flask_login import LoginManager
from flask_wtf import Form
bp = Blueprint('auth', __name__)
class LoginForm(Form):
# define your login form
#bp.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
# do custom login stuff
return redirect(url_for('index'))
return render_template('auth/login.html', form=form)
def init_app(app, user_model):
# have to pass in the user model since it's different between apps
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
#login_manager.user_loader
def company_user_loader(id):
user = user_model.query.get(id)
# do custom user loading stuff
return user
app.register_blueprint(bp, url_prefix='/auth')
company_auth/setup.py
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(
name='company_auth',
version='1.0',
py_modules=['company_auth'],
url='http://davidism.com/',
license='BSD',
author='davidism',
author_email='davidism#gmail.com',
description='Flask extension for company auth',
requires=['flask']
)
Create a distribution of the package to install in other projects.
$ python setup.py sdist
For each project, install the package, import and run the init_app function, and provide the auth templates. (Your extension could include default templates too, but this answer would get gigantic if I go down that path. See Flask-Security for an example of default templates.)
$ project_env/bin/activate
$ pip install /path/to/company_auth/dist/company_auth-1.0.tar.gz
Create the auth templates:
project/
templates/
auth/
login.html
app.py
Set up the app with the custom auth:
import company_auth
company_auth.init_app()