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 authored and dakcarto committed Oct 27, 2017
1 parent d259279 commit 7f96c5b
Showing 1 changed file with 43 additions and 26 deletions.
69 changes: 43 additions & 26 deletions tests/src/python/qgis_wrapped_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,32 +103,36 @@
(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
import signal
import ssl
import copy
import urllib.parse
from http.server import BaseHTTPRequestHandler, HTTPServer
from qgis.core import QgsApplication
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse

QGIS_SERVER_PORT = int(os.environ.get('QGIS_SERVER_PORT', '8081'))
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 @@ -139,12 +143,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 @@ -190,7 +198,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 @@ -243,7 +252,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 @@ -261,7 +271,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 @@ -285,7 +296,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 @@ -307,9 +319,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 @@ -323,7 +337,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 @@ -336,8 +351,10 @@ def do_GET(self, post_body=None):
# CGI vars:
headers = {}
for k, v in self.headers.items():
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)
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)
response = QgsBufferServerResponse()
qgs_server.handleRequest(request, response)

Expand Down Expand Up @@ -369,7 +386,7 @@ def do_POST(self):
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 7f96c5b

Please sign in to comment.