You've already forked oncall
mirror of
https://github.com/linkedin/oncall.git
synced 2025-11-26 23:10:47 +02:00
python 3.10 support (#385)
* upgrade to python 3.10 may break compatibility with older python 3.x versions
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
bash .ci/run_mysql_docker.sh
|
||||
sudo apt-get update
|
||||
sudo apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev
|
||||
sudo apt-get install libsasl2-dev python3-dev libldap2-dev libssl-dev
|
||||
python setup.py develop
|
||||
pip install -e .[dev]
|
||||
|
||||
|
||||
@@ -2,4 +2,4 @@ echo "[*] Spinning up mysql through docker"
|
||||
docker run -p 3306:3306 --name mysql \
|
||||
-e MYSQL_ALLOW_EMPTY_PASSWORD=1 \
|
||||
-e MYSQL_ROOT_HOST=% \
|
||||
-d mysql/mysql-server:5.7
|
||||
-d mysql/mysql-server:8.0
|
||||
|
||||
@@ -2,8 +2,8 @@ version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/python:3.7-stretch-browsers
|
||||
- image: mysql/mysql-server:5.7.33
|
||||
- image: cimg/python:3.10.8-browsers
|
||||
- image: mysql/mysql-server:8.0
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=1234
|
||||
- MYSQL_ROOT_HOST=%
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libsasl2-dev python3-dev libldap2-dev libssl-dev mysql-server
|
||||
sudo apt-get install libsasl2-dev python3-dev libldap2-dev libssl-dev mysql-client
|
||||
- run:
|
||||
name: Prepare virtualenv
|
||||
command: |
|
||||
|
||||
@@ -10,7 +10,7 @@ Development setup
|
||||
-----------------
|
||||
### Prerequisites
|
||||
|
||||
* Debian/Ubuntu - `sudo apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev python-pip python-setuptools mysql-server mysql-client`
|
||||
* Debian/Ubuntu - `sudo apt-get install libsasl2-dev python3-dev libldap2-dev libssl-dev python-pip python-setuptools mysql-server mysql-client`
|
||||
|
||||
### Install
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ class TestLogin(TestCase):
|
||||
ReqBodyMiddleware(),
|
||||
])
|
||||
api.req_options.auto_parse_form_urlencoded = False
|
||||
self.api = api
|
||||
self.api.add_route('/login', login)
|
||||
self.api.add_route('/logout', logout)
|
||||
self.api.add_route('/dummy/{user}', self.UserDummy())
|
||||
self.api.add_route('/dummy2/{team}', self.TeamDummy())
|
||||
self.api = SessionMiddleware(self.api, self.session_opts)
|
||||
self.app = api
|
||||
self.app.add_route('/login', login)
|
||||
self.app.add_route('/logout', logout)
|
||||
self.app.add_route('/dummy/{user}', self.UserDummy())
|
||||
self.app.add_route('/dummy2/{team}', self.TeamDummy())
|
||||
self.app = SessionMiddleware(self.app, self.session_opts)
|
||||
|
||||
self.user_name = 'test_login_user'
|
||||
self.admin_name = 'test_login_admin'
|
||||
@@ -110,7 +110,7 @@ class TestLogin(TestCase):
|
||||
# Test good login, auth check on self
|
||||
re = self.simulate_post('/login', body='username=%s&password=abc' % self.user_name)
|
||||
assert re.status_code == 200
|
||||
cookies = re.headers['set-cookie']
|
||||
cookies = re.headers.get('set-cookie')
|
||||
token = str(re.json['csrf_token'])
|
||||
re = self.simulate_get('/dummy/'+self.user_name, headers={'X-CSRF-TOKEN': token, 'Cookie': cookies})
|
||||
assert re.status_code == 200
|
||||
@@ -118,7 +118,7 @@ class TestLogin(TestCase):
|
||||
# Test good login, auth check on manager
|
||||
re = self.simulate_post('/login', body='username=%s&password=abc' % self.admin_name)
|
||||
assert re.status_code == 200
|
||||
cookies = re.headers['set-cookie']
|
||||
cookies = re.headers.get('set-cookie')
|
||||
token = str(re.json['csrf_token'])
|
||||
re = self.simulate_get('/dummy/'+self.user_name, headers={'X-CSRF-TOKEN': token, 'Cookie': cookies})
|
||||
assert re.status_code == 200
|
||||
@@ -127,14 +127,14 @@ class TestLogin(TestCase):
|
||||
# Test good login, auth check on manager
|
||||
re = self.simulate_post('/login', body='username=%s&password=abc' % self.admin_name)
|
||||
assert re.status_code == 200
|
||||
cookies = re.headers['set-cookie']
|
||||
cookies = re.headers.get('set-cookie')
|
||||
token = str(re.json['csrf_token'])
|
||||
re = self.simulate_get('/dummy2/'+self.team_name, headers={'X-CSRF-TOKEN': token, 'Cookie': cookies})
|
||||
assert re.status_code == 200
|
||||
|
||||
def test_logout(self):
|
||||
re = self.simulate_post('/login', body='username=%s&password=abc' % self.user_name)
|
||||
cookies = re.headers['set-cookie']
|
||||
cookies = re.headers.get('set-cookie')
|
||||
assert re.status_code == 200
|
||||
token = str(re.json['csrf_token'])
|
||||
try:
|
||||
@@ -151,6 +151,6 @@ class TestLogin(TestCase):
|
||||
# Test good login, auth check on manager
|
||||
re = self.simulate_post('/login', body='username=%s&password=abc' % self.admin_name)
|
||||
assert re.status_code == 200
|
||||
cookies = re.headers['set-cookie']
|
||||
cookies = re.headers.get('set-cookie')
|
||||
re = self.simulate_get('/dummy2/'+self.team_name, headers={'X-CSRF-TOKEN': 'foo', 'Cookie': cookies})
|
||||
assert re.status_code == 401
|
||||
|
||||
17
setup.py
17
setup.py
@@ -27,22 +27,21 @@ setuptools.setup(
|
||||
packages=setuptools.find_packages('src'),
|
||||
include_package_data=True,
|
||||
install_requires=[
|
||||
'falcon==1.4.1',
|
||||
'falcon==3.1.1',
|
||||
'falcon-cors',
|
||||
'greenlet==0.4.16',
|
||||
'greenlet==2.0.1',
|
||||
'gevent==22.10.2',
|
||||
'asn1crypto==1.0.0',
|
||||
'gevent==1.4.0',
|
||||
'ujson',
|
||||
'markupsafe==2.0.1',
|
||||
'sqlalchemy',
|
||||
'PyYAML',
|
||||
'PyMYSQL',
|
||||
'phonenumbers',
|
||||
'jinja2==2.11.3',
|
||||
'streql',
|
||||
'jinja2==3.0.3',
|
||||
'webassets',
|
||||
'beaker',
|
||||
'cryptography==2.3',
|
||||
'cryptography==3.1',
|
||||
'python-ldap',
|
||||
'pytz',
|
||||
'irisclient',
|
||||
@@ -55,11 +54,11 @@ setuptools.setup(
|
||||
'ldap': ['python-ldap'],
|
||||
'prometheus': ['prometheus_client'],
|
||||
'dev': [
|
||||
'pytest',
|
||||
'pytest==7.1.2',
|
||||
'pytest-mock',
|
||||
'requests',
|
||||
'gunicorn',
|
||||
'flake8',
|
||||
'gunicorn==20.1.0',
|
||||
'flake8==6.0.0',
|
||||
'Sphinx==1.5.6',
|
||||
'sphinxcontrib-httpdomain',
|
||||
'sphinx_rtd_theme',
|
||||
|
||||
@@ -38,11 +38,11 @@ class ReqBodyMiddleware(object):
|
||||
we often need the post body twice (once for authentication and once in the handler method). To avoid this
|
||||
problem, we read the post body into the request context and access it from there.
|
||||
|
||||
IMPORTANT NOTE: Because we use stream.read() here, all other uses of this method will return '', not the post body.
|
||||
IMPORTANT NOTE: Because we use bounded_stream.read() here, all other uses of this method will return '', not the post body.
|
||||
'''
|
||||
|
||||
def process_request(self, req, resp):
|
||||
req.context['body'] = req.stream.read()
|
||||
req.context['body'] = req.bounded_stream.read()
|
||||
|
||||
|
||||
class AuthMiddleware(object):
|
||||
@@ -76,6 +76,7 @@ def init_falcon_api(config):
|
||||
application = falcon.API(middleware=middlewares)
|
||||
application.req_options.auto_parse_form_urlencoded = False
|
||||
application.set_error_serializer(json_error_serializer)
|
||||
application.req_options.strip_url_path_trailing_slash = True
|
||||
from .auth import init as init_auth
|
||||
init_auth(application, config['auth'])
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import time
|
||||
import hmac
|
||||
import hashlib
|
||||
import base64
|
||||
from streql import equals
|
||||
import importlib
|
||||
from falcon import HTTPUnauthorized, HTTPForbidden, Request
|
||||
from .. import db
|
||||
@@ -131,7 +130,7 @@ def is_client_digest_valid(client_digest, api_key, window, method, path, body):
|
||||
text = '%s %s %s %s' % (window, method, path, body)
|
||||
HMAC = hmac.new(api_key, text.encode('utf-8'), hashlib.sha512)
|
||||
digest = base64.urlsafe_b64encode(HMAC.digest())
|
||||
if equals(client_digest, digest):
|
||||
if hmac.compare_digest(bytes(client_digest, 'utf-8'), digest):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ class StaticResource(object):
|
||||
filepath = path.join(STATIC_ROOT, self.path, secure_filename(filename))
|
||||
try:
|
||||
resp.stream = open(filepath, 'rb')
|
||||
resp.stream_len = path.getsize(filepath)
|
||||
resp.content_length = path.getsize(filepath)
|
||||
except IOError:
|
||||
raise HTTPNotFound()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user