kopia lustrzana https://github.com/OpenDroneMap/WebODM
External auto auth working
rodzic
89a6aca5f0
commit
73052fb2ec
|
@ -0,0 +1,38 @@
|
|||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import login
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import exceptions, permissions, parsers
|
||||
from rest_framework.response import Response
|
||||
from app.auth.backends import get_user_from_external_auth_response
|
||||
import requests
|
||||
from webodm import settings
|
||||
|
||||
class ExternalTokenAuth(APIView):
|
||||
permission_classes = (permissions.AllowAny,)
|
||||
parser_classes = (parsers.JSONParser, parsers.FormParser,)
|
||||
|
||||
def post(self, request):
|
||||
# This should never happen
|
||||
if settings.EXTERNAL_AUTH_ENDPOINT == '':
|
||||
return Response({'error': 'EXTERNAL_AUTH_ENDPOINT not set'})
|
||||
|
||||
token = request.COOKIES.get('external_access_token', '')
|
||||
if token == '':
|
||||
return Response({'error': 'external_access_token cookie not set'})
|
||||
|
||||
try:
|
||||
r = requests.post(settings.EXTERNAL_AUTH_ENDPOINT, headers={
|
||||
'Authorization': "Bearer %s" % token
|
||||
})
|
||||
res = r.json()
|
||||
if res.get('user_id') is not None:
|
||||
user = get_user_from_external_auth_response(res)
|
||||
if user is not None:
|
||||
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
|
||||
return Response({'redirect': '/'})
|
||||
else:
|
||||
return Response({'error': 'Invalid credentials'})
|
||||
else:
|
||||
return Response({'error': res.get('message', 'Invalid external server response')})
|
||||
except Exception as e:
|
||||
return Response({'error': str(e)})
|
|
@ -13,6 +13,7 @@ from .tiler import TileJson, Bounds, Metadata, Tiles, Export
|
|||
from .potree import Scene, CameraView
|
||||
from .workers import CheckTask, GetTaskResult
|
||||
from .users import UsersList
|
||||
from .externalauth import ExternalTokenAuth
|
||||
from webodm import settings
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
|
@ -63,3 +64,6 @@ urlpatterns = [
|
|||
if settings.ENABLE_USERS_API:
|
||||
urlpatterns.append(url(r'users', UsersList.as_view()))
|
||||
|
||||
if settings.EXTERNAL_AUTH_ENDPOINT != '':
|
||||
urlpatterns.append(url(r'^external-token-auth/', ExternalTokenAuth.as_view()))
|
||||
|
||||
|
|
|
@ -8,6 +8,57 @@ import logging
|
|||
|
||||
logger = logging.getLogger('app.logger')
|
||||
|
||||
def get_user_from_external_auth_response(res):
|
||||
if 'message' in res or 'error' in res:
|
||||
return None
|
||||
|
||||
if 'user_id' in res and 'username' in res:
|
||||
try:
|
||||
user = User.objects.get(pk=res['user_id'])
|
||||
|
||||
# Update user info
|
||||
if user.username != res['username']:
|
||||
user.username = res['username']
|
||||
user.save()
|
||||
|
||||
# Update quotas
|
||||
maxQuota = -1
|
||||
if 'maxQuota' in res:
|
||||
maxQuota = res['maxQuota']
|
||||
if 'node' in res and 'limits' in res['node'] and 'maxQuota' in res['node']['limits']:
|
||||
maxQuota = res['node']['limits']['maxQuota']
|
||||
|
||||
if user.profile.quota != maxQuota:
|
||||
user.profile.quota = maxQuota
|
||||
user.save()
|
||||
except User.DoesNotExist:
|
||||
user = User(pk=res['user_id'], username=username)
|
||||
user.save()
|
||||
|
||||
# Setup/update processing node
|
||||
if ('api_key' in res or 'token' in res) and 'node' in res:
|
||||
hostname = res['node']['hostname']
|
||||
port = res['node']['port']
|
||||
token = res['api_key'] if 'api_key' in res else res['token']
|
||||
|
||||
try:
|
||||
node = ProcessingNode.objects.get(token=token)
|
||||
if node.hostname != hostname or node.port != port:
|
||||
node.hostname = hostname
|
||||
node.port = port
|
||||
node.save()
|
||||
|
||||
except ProcessingNode.DoesNotExist:
|
||||
node = ProcessingNode(hostname=hostname, port=port, token=token)
|
||||
node.save()
|
||||
|
||||
if not user.has_perm('view_processingnode', node):
|
||||
assign_perm('view_processingnode', user, node)
|
||||
|
||||
return user
|
||||
else:
|
||||
return None
|
||||
|
||||
class ExternalBackend(ModelBackend):
|
||||
def authenticate(self, request, username=None, password=None):
|
||||
if EXTERNAL_AUTH_ENDPOINT == "":
|
||||
|
@ -20,57 +71,7 @@ class ExternalBackend(ModelBackend):
|
|||
}, headers={'Accept': 'application/json'})
|
||||
res = r.json()
|
||||
|
||||
# logger.info(res)
|
||||
|
||||
if 'message' in res or 'error' in res:
|
||||
return None
|
||||
|
||||
if 'user_id' in res:
|
||||
try:
|
||||
user = User.objects.get(pk=res['user_id'])
|
||||
|
||||
# Update user info
|
||||
if user.username != username:
|
||||
user.username = username
|
||||
user.save()
|
||||
|
||||
# Update quotas
|
||||
maxQuota = -1
|
||||
if 'maxQuota' in res:
|
||||
maxQuota = res['maxQuota']
|
||||
if 'node' in res and 'limits' in res['node'] and 'maxQuota' in res['node']['limits']:
|
||||
maxQuota = res['node']['limits']['maxQuota']
|
||||
|
||||
if user.profile.quota != maxQuota:
|
||||
user.profile.quota = maxQuota
|
||||
user.save()
|
||||
except User.DoesNotExist:
|
||||
user = User(pk=res['user_id'], username=username)
|
||||
user.save()
|
||||
|
||||
# Setup/update processing node
|
||||
if ('api_key' in res or 'token' in res) and 'node' in res:
|
||||
hostname = res['node']['hostname']
|
||||
port = res['node']['port']
|
||||
token = res['api_key'] if 'api_key' in res else res['token']
|
||||
|
||||
try:
|
||||
node = ProcessingNode.objects.get(token=token)
|
||||
if node.hostname != hostname or node.port != port:
|
||||
node.hostname = hostname
|
||||
node.port = port
|
||||
node.save()
|
||||
|
||||
except ProcessingNode.DoesNotExist:
|
||||
node = ProcessingNode(hostname=hostname, port=port, token=token)
|
||||
node.save()
|
||||
|
||||
if not user.has_perm('view_processingnode', node):
|
||||
assign_perm('view_processingnode', user, node)
|
||||
|
||||
return user
|
||||
else:
|
||||
return None
|
||||
return get_user_from_external_auth_response(res)
|
||||
except:
|
||||
return None
|
||||
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
{% endif %}
|
||||
|
||||
{% is_single_user_mode as autologin %}
|
||||
{% external_auth_endpoint as ext_auth_ep %}
|
||||
{% has_external_auth as ext_auth %}
|
||||
|
||||
{% if autologin %}
|
||||
<script>location.href='/';</script>
|
||||
{% else %}
|
||||
<form id="loginForm" {% if ext_auth_ep != "" %} style="display: none" {% endif %} action="{% url 'login' %}" method="post" class="form-horizontal" role="form">{% csrf_token %}
|
||||
<form id="loginForm" {% if ext_auth %} style="display: none" {% endif %} action="{% url 'login' %}" method="post" class="form-horizontal" role="form">{% csrf_token %}
|
||||
{% for field in form %}
|
||||
{% include 'registration/form_field.html' %}
|
||||
{% endfor %}
|
||||
|
@ -36,34 +36,47 @@
|
|||
</div>
|
||||
</form>
|
||||
|
||||
{% if ext_auth_ep != '' %}
|
||||
{% if ext_auth %}
|
||||
<div class="text-center" id="authLoading">
|
||||
<i class="fa fa-spin fa-circle-notch fa-spin fa-fw fa-2x"></i>
|
||||
</div>
|
||||
<script>
|
||||
function getCookie(name) {
|
||||
function getAutoLoginCookie() {
|
||||
var value = "; " + document.cookie;
|
||||
var parts = value.split("; " + name + "=");
|
||||
var parts = value.split("; autologin=");
|
||||
if (parts.length === 2) return parts.pop().split(';').shift();
|
||||
}
|
||||
function delCookie(name) {
|
||||
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||
function delAutoLoginCookie() {
|
||||
var domain = getAutoLoginCookie();
|
||||
document.cookie = 'autologin=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=' + domain + ';';
|
||||
}
|
||||
function showLoginForm(){
|
||||
$("#authLoading").hide();
|
||||
$("#loginForm").show();
|
||||
}
|
||||
$(function(){
|
||||
if (getCookie("autologin") !== undefined){
|
||||
if (getAutoLoginCookie() !== undefined){
|
||||
$.ajax({
|
||||
url: "{{ ext_auth_ep }}",
|
||||
url: "/api/external-token-auth/",
|
||||
type: "POST",
|
||||
xhrFields: {
|
||||
withCredentials: true
|
||||
},
|
||||
}).done(function(res){
|
||||
console.log(res);
|
||||
// delCookie("autologin");
|
||||
delAutoLoginCookie();
|
||||
if (res.redirect){
|
||||
location.href = res.redirect;
|
||||
}else{
|
||||
if (res.error) console.error(res.error);
|
||||
showLoginForm();
|
||||
}
|
||||
}).fail(function(){
|
||||
|
||||
// delCookie("autologin");
|
||||
delAutoLoginCookie();
|
||||
showLoginForm();
|
||||
console.error("Auto login failed");
|
||||
});
|
||||
}else{
|
||||
$("#authLoading").hide();
|
||||
$("#loginForm").show();
|
||||
showLoginForm();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -10,8 +10,8 @@ register = template.Library()
|
|||
logger = logging.getLogger('app.logger')
|
||||
|
||||
@register.simple_tag
|
||||
def external_auth_endpoint():
|
||||
return settings.EXTERNAL_AUTH_ENDPOINT
|
||||
def has_external_auth():
|
||||
return settings.EXTERNAL_AUTH_ENDPOINT != ""
|
||||
|
||||
@register.filter
|
||||
def disk_size(megabytes):
|
||||
|
|
Ładowanie…
Reference in New Issue