Skip to content

Commit

Permalink
fixed mixing of token object and string in login/logout
Browse files Browse the repository at this point in the history
  • Loading branch information
giohappy committed Feb 4, 2019
1 parent bdde3b1 commit 2ccaece
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 65 deletions.
67 changes: 13 additions & 54 deletions geonode/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,12 @@

from geonode.people.enumerations import ROLE_VALUES

from oauthlib.common import generate_token
from oauth2_provider.models import AccessToken, get_application_model
from geonode.base.oauth import (get_or_create_token,
delete_old_tokens,
set_session_token,
get_session_token,
remove_session_token)
from oauth2_provider.models import AccessToken

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -1458,38 +1462,7 @@ def do_login(sender, user, request, **kwargs):
if user and user.is_authenticated():
token = None
try:
Application = get_application_model()
app = Application.objects.get(name="GeoServer")

# Lets create a new one
token = generate_token()

# 1 day expiration time by default
_expire_seconds = getattr(settings, 'ACCESS_TOKEN_EXPIRE_SECONDS', 86400)
_expire_time = datetime.datetime.now(timezone.get_current_timezone())
_expire_delta = datetime.timedelta(seconds=_expire_seconds)

# Let's create the new AUTH TOKEN
existing_token = None
try:
existing_token = AccessToken.objects.filter(user=user, application=app).order_by('-expires').first()
if existing_token and existing_token.expires < _expire_time:
existing_token = None
existing_token.delete()
except BaseException:
existing_token = None
tb = traceback.format_exc()
if tb:
logger.debug(tb)

if not existing_token:
(token, created) = AccessToken.objects.get_or_create(
user=user,
application=app,
expires=_expire_time + _expire_delta,
token=token)
else:
token = existing_token
token = get_or_create_token(user)
except BaseException:
u = uuid.uuid1()
token = u.hex
Expand All @@ -1515,7 +1488,7 @@ def do_login(sender, user, request, **kwargs):
u = uuid.uuid1()
jsessionid = u.hex

request.session['access_token'] = token
set_session_token(request.session, token)
request.session['JSESSIONID'] = jsessionid


Expand All @@ -1528,27 +1501,14 @@ def do_logout(sender, user, request, **kwargs):
header_params = {}
if 'access_token' in request.session:
try:
Application = get_application_model()
app = Application.objects.get(name="GeoServer")

_expire_time = datetime.datetime.now(timezone.get_current_timezone())

# Lets delete the old one
try:
old_tokens = AccessToken.objects.filter(user=user, application=app).order_by('-expires')
for old in old_tokens:
if old.expires < _expire_time:
old.delete()
except BaseException:
tb = traceback.format_exc()
if tb:
logger.debug(tb)
delete_old_tokens(user)
except BaseException:
pass

# Do GeoServer Logout
if request and 'access_token' in request.session:
access_token = request.session['access_token']

if request:
access_token = get_session_token(request.session)
else:
access_token = None

Expand Down Expand Up @@ -1594,8 +1554,7 @@ def do_logout(sender, user, request, **kwargs):
if tb:
logger.debug(tb)

if 'access_token' in request.session:
del request.session['access_token']
remove_session_token(request.session)

request.session.modified = True

Expand Down
96 changes: 91 additions & 5 deletions geonode/base/oauth.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,110 @@
import datetime
import base64
import logging
import traceback

from django.utils import timezone
from django.conf import settings
from django.contrib.auth import authenticate
from oauth2_provider.models import AccessToken, get_application_model
from oauthlib.common import generate_token

def make_token_expiration():
_expire_seconds = getattr(settings, 'ACCESS_TOKEN_EXPIRE_SECONDS', 86400)
logger = logging.getLogger(__name__)


def make_token_expiration(seconds = 86400):
_expire_seconds = getattr(settings, 'ACCESS_TOKEN_EXPIRE_SECONDS', seconds)
_expire_time = datetime.datetime.now(timezone.get_current_timezone())
_expire_delta = datetime.timedelta(seconds=_expire_seconds)
return _expire_time + _expire_delta


def is_old_token(token, seconds = 86400):
_expire_seconds = getattr(settings, 'ACCESS_TOKEN_EXPIRE_SECONDS', seconds)
_expire_time = datetime.datetime.now(timezone.get_current_timezone())
_expire_delta = datetime.timedelta(seconds=_expire_seconds)

token.expires < _expire_time


def create_auth_token(user, client="GeoServer"):
expires = make_token_expiration()
Application = get_application_model()
app = Application.objects.get(name=client)
access_token = AccessToken.objects.get(
(access_token, created) = AccessToken.objects.get_or_create(
user=user,
application=app,
expires=expires,
token=generate_token())
return access_token

def extend_oauth_token(token):

def extend_token(token):
access_token = AccessToken.objects.get(id=token.id)
expires = make_token_expiration()
access_token.expires = expires
access_token.save()


def get_auth_token(user, client="GeoServer"):
Application = get_application_model()
app = Application.objects.get(name=client)
access_token = AccessToken.objects.filter(user=user, application=app).order_by('-expires').first()
return access_token


def get_auth_token_from_auth_header(auth_header):
def get_or_create_token(user, client="GeoServer"):
application = get_application_model()
app = application.objects.get(name=client)

# Lets create a new one
token = generate_token()

# 1 day expiration time by default
_expire_seconds = getattr(settings, 'ACCESS_TOKEN_EXPIRE_SECONDS', 86400)
_expire_time = datetime.datetime.now(timezone.get_current_timezone())
_expire_delta = datetime.timedelta(seconds=_expire_seconds)

# Let's create the new AUTH TOKEN
existing_token = None
try:
existing_token = AccessToken.objects.filter(user=user, application=app).order_by('-expires').first()
if existing_token and is_old_token(existing_token):
existing_token.delete()
existing_token = None
except BaseException:
existing_token = None
tb = traceback.format_exc()
if tb:
logger.debug(tb)

if not existing_token:
token = create_auth_token(user, client)
else:
token = existing_token

return token


def delete_old_tokens(user, client='Geoserver'):
application = get_application_model()
app = application.objects.get(name=client)

_expire_time = datetime.datetime.now(timezone.get_current_timezone())

# Lets delete the old one
try:
old_tokens = AccessToken.objects.filter(user=user, application=app).order_by('-expires')
for old in old_tokens:
if old.expires < _expire_time:
old.delete()
except BaseException:
tb = traceback.format_exc()
if tb:
logger.debug(tb)


def get_token_from_auth_header(auth_header):
if 'Basic' in auth_header:
encoded_credentials = auth_header.split(' ')[1] # Removes "Basic " to isolate credentials
decoded_credentials = base64.b64decode(encoded_credentials).decode("utf-8").split(':')
Expand All @@ -49,3 +116,22 @@ def get_auth_token_from_auth_header(auth_header):
elif 'Bearer' in auth_header:
return auth_header.replace('Bearer ', '')
return None


def set_session_token(session, token):
session['access_token'] = str(token)


def get_session_token(session):
return session.get('access_token', None)


def get_token_object_from_session(session):
return AccessToken.objects.get(token=session['access_token'])


def remove_session_token(session):
if 'access_token' in session:
del session['access_token']


14 changes: 8 additions & 6 deletions geonode/proxy/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
check_ogc_backend,
get_dir_time_suffix,
zip_dir)
from geonode.base.oauth import extend_oauth_token, get_auth_token_from_auth_header
from geonode.base.oauth import (extend_token,
get_token_from_auth_header,
get_token_object_from_session)
from geonode import geoserver, qgis_server # noqa

TIMEOUT = 30
Expand Down Expand Up @@ -160,14 +162,14 @@ def proxy(request, url=None, response_callback=None,
'HTTP_AUTHORIZATION',
request.META.get('HTTP_AUTHORIZATION2'))
if auth_header:
access_token = get_auth_token_from_auth_header(auth_header)
access_token = get_token_from_auth_header(auth_header)
# otherwise we check if a session is active
elif request and 'access_token' in request.session:
access_token = request.session['access_token']
elif request and request.user.is_authenticated :
access_token = get_token_object_from_session(request.session)

# we extend the token in case the session is active but the token expired
if access_token and access_token.is_expired():
extend_oauth_token(access_token)
request.session['access_token'] = access_token
extend_token(access_token)

if access_token:
headers['Authorization'] = 'Bearer %s' % access_token
Expand Down

0 comments on commit 2ccaece

Please sign in to comment.