Skip to content

Commit

Permalink
Pass urlencoded URL to the oauth handler
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Jun 25, 2018
1 parent 65b2909 commit 5ee767a
Showing 1 changed file with 46 additions and 16 deletions.
62 changes: 46 additions & 16 deletions tests/src/python/qgis_wrapped_server.py
Expand Up @@ -113,16 +113,27 @@
(at your option) any later version.
"""

import copy
import os
import signal
import ssl
import sys
import urllib.parse

from http.server import BaseHTTPRequestHandler, HTTPServer
from qgis.core import QgsApplication
from qgis.server import (QgsBufferServerRequest, QgsBufferServerResponse,
QgsServer, QgsServerRequest)

__author__ = 'Alessandro Pasotti'
__date__ = '05/15/2016'
__copyright__ = 'Copyright 2016, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'


import os

# Needed on Qt 5 so that the serialization of XML is consistent among all executions
# Needed on Qt 5 so that the serialization of XML is consistent among all
# executions
os.environ['QT_HASH_SEED'] = '1'

import sys
Expand All @@ -142,7 +153,8 @@
QGIS_SERVER_HOST = os.environ.get('QGIS_SERVER_HOST', '127.0.0.1')

# HTTP Basic
QGIS_SERVER_HTTP_BASIC_AUTH = os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH', False)
QGIS_SERVER_HTTP_BASIC_AUTH = os.environ.get(
'QGIS_SERVER_HTTP_BASIC_AUTH', False)
QGIS_SERVER_USERNAME = os.environ.get('QGIS_SERVER_USERNAME', 'username')
QGIS_SERVER_PASSWORD = os.environ.get('QGIS_SERVER_PASSWORD', 'password')

Expand All @@ -153,12 +165,16 @@
QGIS_SERVER_PKI_USERNAME = os.environ.get('QGIS_SERVER_PKI_USERNAME')

# OAuth2 authentication
QGIS_SERVER_OAUTH2_CERTIFICATE = os.environ.get('QGIS_SERVER_OAUTH2_CERTIFICATE')
QGIS_SERVER_OAUTH2_CERTIFICATE = os.environ.get(
'QGIS_SERVER_OAUTH2_CERTIFICATE')
QGIS_SERVER_OAUTH2_KEY = os.environ.get('QGIS_SERVER_OAUTH2_KEY')
QGIS_SERVER_OAUTH2_AUTHORITY = os.environ.get('QGIS_SERVER_OAUTH2_AUTHORITY')
QGIS_SERVER_OAUTH2_USERNAME = os.environ.get('QGIS_SERVER_OAUTH2_USERNAME', 'username')
QGIS_SERVER_OAUTH2_PASSWORD = os.environ.get('QGIS_SERVER_OAUTH2_PASSWORD', 'password')
QGIS_SERVER_OAUTH2_TOKEN_EXPIRES_IN = os.environ.get('QGIS_SERVER_OAUTH2_TOKEN_EXPIRES_IN', 3600)
QGIS_SERVER_OAUTH2_USERNAME = os.environ.get(
'QGIS_SERVER_OAUTH2_USERNAME', 'username')
QGIS_SERVER_OAUTH2_PASSWORD = os.environ.get(
'QGIS_SERVER_OAUTH2_PASSWORD', 'password')
QGIS_SERVER_OAUTH2_TOKEN_EXPIRES_IN = os.environ.get(
'QGIS_SERVER_OAUTH2_TOKEN_EXPIRES_IN', 3600)

# Check if PKI is enabled
QGIS_SERVER_PKI_AUTH = (
Expand Down Expand Up @@ -218,7 +234,8 @@ def responseComplete(self):
# No auth ...
handler.clear()
handler.setResponseHeader('Status', '401 Authorization required')
handler.setResponseHeader('WWW-Authenticate', 'Basic realm="QGIS Server"')
handler.setResponseHeader(
'WWW-Authenticate', 'Basic realm="QGIS Server"')
handler.appendBody(b'<h1>Authorization required</h1>')

filter = HTTPBasicFilter(qgs_server.serverInterface())
Expand Down Expand Up @@ -307,7 +324,8 @@ def save_bearer_token(self, token, request, *args, **kwargs):
# access_token and the refresh_token and set expiration for the
# access_token to now + expires_in seconds.
_tokens[token['access_token']] = copy.copy(token)
_tokens[token['access_token']]['expiration'] = datetime.now().timestamp() + int(token['expires_in'])
_tokens[token['access_token']]['expiration'] = datetime.now(
).timestamp() + int(token['expires_in'])

def validate_bearer_token(self, token, scopes, request):
"""Check the token"""
Expand All @@ -325,7 +343,8 @@ def get_original_scopes(self, refresh_token, request, *args, **kwargs):
return []

validator = SimpleValidator()
oauth_server = LegacyApplicationServer(validator, token_expires_in=QGIS_SERVER_OAUTH2_TOKEN_EXPIRES_IN)
oauth_server = LegacyApplicationServer(
validator, token_expires_in=QGIS_SERVER_OAUTH2_TOKEN_EXPIRES_IN)

class OAuth2Filter(QgsServerFilter):
"""This filter provides testing endpoint for OAuth2 Resource Owner Grant Flow
Expand All @@ -349,7 +368,8 @@ def _token(ttl):
old_expires_in = oauth_server.default_token_type.expires_in
# Hacky way to dynamically set token expiration time
oauth_server.default_token_type.expires_in = ttl
headers, payload, code = oauth_server.create_token_response('/token', 'post', body, {})
headers, payload, code = oauth_server.create_token_response(
'/token', 'post', body, {})
oauth_server.default_token_type.expires_in = old_expires_in
for k, v in headers.items():
handler.setResponseHeader(k, v)
Expand All @@ -371,9 +391,11 @@ def _token(ttl):
# Check for valid token
auth = handler.requestHeader('HTTP_AUTHORIZATION')
if auth:
result, response = oauth_server.verify_request(handler.url(), 'post', '', {'Authorization': auth})
result, response = oauth_server.verify_request(
urllib.parse.quote_plus(handler.url(), safe='/:?=&'), 'post', '', {'Authorization': auth})
if result:
# This is a test endpoint for OAuth2, it requires a valid token
# This is a test endpoint for OAuth2, it requires a valid
# token
if handler.url().find('/result') != -1:
handler.clear()
handler.appendBody(b'Valid Token: enjoy OAuth2')
Expand All @@ -387,7 +409,8 @@ def _token(ttl):
handler.clear()
handler.setStatusCode(401)
handler.setResponseHeader('Status', '401 Unauthorized')
handler.setResponseHeader('WWW-Authenticate', 'Bearer realm="QGIS Server"')
handler.setResponseHeader(
'WWW-Authenticate', 'Bearer realm="QGIS Server"')
handler.appendBody(b'Invalid Token: Authorization required.')

filter = OAuth2Filter(qgs_server.serverInterface())
Expand All @@ -401,10 +424,17 @@ def do_GET(self, post_body=None):
# CGI vars:
headers = {}
for k, v in self.headers.items():
<<<<<<< a7fb4238893336c8d5b2b4802f63588175e70c83
headers['HTTP_%s' % k.replace(' ', '-').replace('-', '_').replace(' ', '-').upper()] = v
if not self.path.startswith('http'):
self.path = "%s://%s:%s%s" % ('https' if https else 'http', QGIS_SERVER_HOST, self.server.server_port, self.path)
request = QgsBufferServerRequest(self.path, (QgsServerRequest.PostMethod if post_body is not None else QgsServerRequest.GetMethod), headers, post_body)
=======
headers['HTTP_%s' % k.replace(
' ', '-').replace('-', '_').replace(' ', '-').upper()] = v
request = QgsBufferServerRequest(
self.path, (QgsServerRequest.PostMethod if post_body is not None else QgsServerRequest.GetMethod), headers, post_body)
>>>>>>> Pass urlencoded URL to the oauth handler
response = QgsBufferServerResponse()
qgs_server.handleRequest(request, response)

Expand Down Expand Up @@ -455,7 +485,7 @@ class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
ca_certs=QGIS_SERVER_OAUTH2_AUTHORITY,
keyfile=QGIS_SERVER_OAUTH2_KEY,
server_side=True,
#cert_reqs=ssl.CERT_REQUIRED, # No certs for OAuth2
# cert_reqs=ssl.CERT_REQUIRED, # No certs for OAuth2
ssl_version=ssl.PROTOCOL_TLSv1)
else:
server.socket = ssl.wrap_socket(
Expand Down

0 comments on commit 5ee767a

Please sign in to comment.