Merge branch 'release/v22.3.0'
This commit is contained in:
@@ -93,7 +93,8 @@ from django.http import (
|
||||
HttpResponse, HttpResponseRedirect,
|
||||
JsonResponse,
|
||||
HttpResponseForbidden, HttpResponseNotAllowed,
|
||||
HttpResponseNotFound, Http404
|
||||
HttpResponseNotFound, Http404,
|
||||
HttpResponseBadRequest,
|
||||
)
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from rowers.forms import (
|
||||
@@ -163,7 +164,7 @@ from rowers.models import (
|
||||
StandardCollection, CourseStandard,
|
||||
VirtualRaceFollower, TombStone, InstantPlan,
|
||||
PlannedSessionStep,InStrokeAnalysis, ForceCurveAnalysis, SyncRecord,
|
||||
UserMessage,
|
||||
UserMessage,APIKey,
|
||||
)
|
||||
from rowers.models import ( RowerPowerForm, RowerHRZonesForm, SimpleRowerPowerForm,
|
||||
RowerForm, RowerCPForm, GraphImage, AdvancedWorkoutForm,
|
||||
@@ -303,6 +304,142 @@ from rowers.weather import get_wind_data, get_airport_code, get_metar_data
|
||||
|
||||
from oauth2_provider.models import Application, Grant, AccessToken
|
||||
|
||||
import base64
|
||||
from django.http import HttpResponse
|
||||
from django.contrib.auth import authenticate, login
|
||||
|
||||
def view_or_apikey(view, request, test_func, realm = "", *args, **kwargs):
|
||||
if test_func(request.user):
|
||||
return view(request, *args, **kwargs)
|
||||
|
||||
if 'Authorization' in request.META:
|
||||
api_key = request.META.get('Authorization')
|
||||
if api_key:
|
||||
try:
|
||||
api_key = APIKey.objects.get(key=api_key, is_active=True)
|
||||
except APIKey.DoesNotExist:
|
||||
raise AuthenticationFailed('Invalid API key')
|
||||
|
||||
login(request, api_key.user, backend='django.contrib.auth.backends.ModelBackend')
|
||||
request.user = api_key.user
|
||||
return view(request, *args, **kwargs)
|
||||
|
||||
response = HttpResponse()
|
||||
response.status_code = 401
|
||||
response['WWW-Authenticate'] = 'Basic realm="%s"' % realm
|
||||
return response
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
def view_or_basicauth(view, request, test_func, realm = "", *args, **kwargs):
|
||||
"""
|
||||
This is a helper function used by both 'logged_in_or_basicauth' and
|
||||
'has_perm_or_basicauth' that does the nitty of determining if they
|
||||
are already logged in or if they have provided proper http-authorization
|
||||
and returning the view if all goes well, otherwise responding with a 401.
|
||||
"""
|
||||
if test_func(request.user):
|
||||
# Already logged in, just return the view.
|
||||
#
|
||||
return view(request, *args, **kwargs)
|
||||
|
||||
# They are not logged in. See if they provided login credentials
|
||||
#
|
||||
if 'HTTP_AUTHORIZATION' in request.META:
|
||||
auth = request.META['HTTP_AUTHORIZATION'].split()
|
||||
if len(auth) == 2:
|
||||
# NOTE: We are only support basic authentication for now.
|
||||
#
|
||||
if auth[0].lower() == "basic":
|
||||
uname, passwd = base64.b64decode(auth[1]).decode("utf-8").split(':')
|
||||
user = authenticate(username=uname, password=passwd)
|
||||
if user is not None:
|
||||
if user.is_active:
|
||||
login(request, user)
|
||||
request.user = user
|
||||
return view(request, *args, **kwargs)
|
||||
|
||||
# Either they did not provide an authorization header or
|
||||
# something in the authorization attempt failed. Send a 401
|
||||
# back to them to ask them to authenticate.
|
||||
#
|
||||
response = HttpResponse()
|
||||
response.status_code = 401
|
||||
response['WWW-Authenticate'] = 'Basic realm="%s"' % realm
|
||||
return response
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
def logged_in_or_apikey(realm = ""):
|
||||
def view_decorator(func):
|
||||
def wrapper(request, *args, **kwargs):
|
||||
return view_or_apikey(func, request,
|
||||
lambda u: u.is_authenticated,
|
||||
realm, *args, **kwargs)
|
||||
return wrapper
|
||||
return view_decorator
|
||||
|
||||
def logged_in_or_basicauth(realm = ""):
|
||||
"""
|
||||
A simple decorator that requires a user to be logged in. If they are not
|
||||
logged in the request is examined for a 'authorization' header.
|
||||
|
||||
If the header is present it is tested for basic authentication and
|
||||
the user is logged in with the provided credentials.
|
||||
|
||||
If the header is not present a http 401 is sent back to the
|
||||
requestor to provide credentials.
|
||||
|
||||
The purpose of this is that in several django projects I have needed
|
||||
several specific views that need to support basic authentication, yet the
|
||||
web site as a whole used django's provided authentication.
|
||||
|
||||
The uses for this are for urls that are access programmatically such as
|
||||
by rss feed readers, yet the view requires a user to be logged in. Many rss
|
||||
readers support supplying the authentication credentials via http basic
|
||||
auth (and they do NOT support a redirect to a form where they post a
|
||||
username/password.)
|
||||
|
||||
Use is simple:
|
||||
|
||||
@logged_in_or_basicauth
|
||||
def your_view:
|
||||
...
|
||||
|
||||
You can provide the name of the realm to ask for authentication within.
|
||||
"""
|
||||
def view_decorator(func):
|
||||
def wrapper(request, *args, **kwargs):
|
||||
return view_or_basicauth(func, request,
|
||||
lambda u: u.is_authenticated,
|
||||
realm, *args, **kwargs)
|
||||
return wrapper
|
||||
return view_decorator
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
def has_perm_or_basicauth(perm, realm = ""):
|
||||
"""
|
||||
This is similar to the above decorator 'logged_in_or_basicauth'
|
||||
except that it requires the logged in user to have a specific
|
||||
permission.
|
||||
|
||||
Use:
|
||||
|
||||
@logged_in_or_basicauth('asforums.view_forumcollection')
|
||||
def your_view:
|
||||
...
|
||||
|
||||
"""
|
||||
def view_decorator(func):
|
||||
def wrapper(request, *args, **kwargs):
|
||||
return view_or_basicauth(func, request,
|
||||
lambda u: u.has_perm(perm),
|
||||
realm, *args, **kwargs)
|
||||
return wrapper
|
||||
return view_decorator
|
||||
|
||||
|
||||
import django_rq
|
||||
queue = django_rq.get_queue('default')
|
||||
queuelow = django_rq.get_queue('low')
|
||||
|
||||
Reference in New Issue
Block a user