You've already forked oncall
mirror of
https://github.com/linkedin/oncall.git
synced 2025-11-28 23:20:23 +02:00
Implement auth_required to force auth on API calls (#216)
This commit is contained in:
committed by
Joe Gillotti
parent
c05869581d
commit
40982732fe
@@ -178,8 +178,10 @@ iris_plan_integration:
|
|||||||
# Configures whether Slack settings will appear in the frontend
|
# Configures whether Slack settings will appear in the frontend
|
||||||
slack_instance: foobar
|
slack_instance: foobar
|
||||||
|
|
||||||
# setting to toggle login splash screen. This will require users to log in to be able to use the app. Set to True to enable and False to disable.
|
# Setting to determine whether the Oncall API/frontend is available unauthenticated.
|
||||||
force_login_splash: False
|
# Set to True to force login splash page and authentication on API calls and False to allow read
|
||||||
|
# APIs without authentication
|
||||||
|
require_auth: False
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
### Oncall user management
|
### Oncall user management
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import re
|
|||||||
from beaker.middleware import SessionMiddleware
|
from beaker.middleware import SessionMiddleware
|
||||||
from falcon_cors import CORS
|
from falcon_cors import CORS
|
||||||
|
|
||||||
from . import db, constants, iris
|
from . import db, constants, iris, auth
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger('oncall.app')
|
logger = logging.getLogger('oncall.app')
|
||||||
@@ -47,17 +47,35 @@ class ReqBodyMiddleware(object):
|
|||||||
req.context['body'] = req.stream.read()
|
req.context['body'] = req.stream.read()
|
||||||
|
|
||||||
|
|
||||||
|
class AuthMiddleware(object):
|
||||||
|
def process_resource(self, req, resp, resource, params):
|
||||||
|
try:
|
||||||
|
if resource.allow_no_auth:
|
||||||
|
return
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
auth_token = req.get_header('AUTHORIZATION')
|
||||||
|
if auth_token:
|
||||||
|
auth.authenticate_application(auth_token, req)
|
||||||
|
else:
|
||||||
|
auth.authenticate_user(req)
|
||||||
|
|
||||||
|
|
||||||
application = None
|
application = None
|
||||||
|
|
||||||
|
|
||||||
def init_falcon_api(config):
|
def init_falcon_api(config):
|
||||||
global application
|
global application
|
||||||
cors = CORS(allow_origins_list=config.get('allow_origins_list', []))
|
cors = CORS(allow_origins_list=config.get('allow_origins_list', []))
|
||||||
application = falcon.API(middleware=[
|
middlewares = [
|
||||||
SecurityHeaderMiddleware(),
|
SecurityHeaderMiddleware(),
|
||||||
ReqBodyMiddleware(),
|
ReqBodyMiddleware(),
|
||||||
cors.middleware
|
cors.middleware
|
||||||
])
|
]
|
||||||
|
if config.get('require_auth'):
|
||||||
|
middlewares.append(AuthMiddleware())
|
||||||
|
application = falcon.API(middleware=middlewares)
|
||||||
application.req_options.auto_parse_form_urlencoded = False
|
application.req_options.auto_parse_form_urlencoded = False
|
||||||
application.set_error_serializer(json_error_serializer)
|
application.set_error_serializer(json_error_serializer)
|
||||||
from .auth import init as init_auth
|
from .auth import init as init_auth
|
||||||
|
|||||||
@@ -241,8 +241,9 @@ def init(application, config):
|
|||||||
check_calendar_auth_by_id = lambda x, y: True
|
check_calendar_auth_by_id = lambda x, y: True
|
||||||
debug_only = lambda function: function
|
debug_only = lambda function: function
|
||||||
|
|
||||||
if config.get('docs'):
|
if config.get('docs') or config.get('require_auth'):
|
||||||
# Replace login_required decorator with identity function for autodoc generation
|
# Replace login_required decorator with identity function for autodoc generation
|
||||||
|
# Also replace if require_auth is True, since AuthMiddleware already handles login for us
|
||||||
global login_required
|
global login_required
|
||||||
login_required = lambda x: x
|
login_required = lambda x: x
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ from oncall import db
|
|||||||
from random import SystemRandom
|
from random import SystemRandom
|
||||||
from . import auth_manager
|
from . import auth_manager
|
||||||
|
|
||||||
|
allow_no_auth = True
|
||||||
|
|
||||||
|
|
||||||
def on_post(req, resp):
|
def on_post(req, resp):
|
||||||
login_info = uri.parse_query_string(req.context['body'])
|
login_info = uri.parse_query_string(req.context['body'])
|
||||||
|
|||||||
@@ -73,12 +73,12 @@ SLACK_INSTANCE = None
|
|||||||
HEADER_COLOR = None
|
HEADER_COLOR = None
|
||||||
IRIS_PLAN_SETTINGS = None
|
IRIS_PLAN_SETTINGS = None
|
||||||
USERCONTACT_UI_READONLY = None
|
USERCONTACT_UI_READONLY = None
|
||||||
LOGIN_SPLASH = None
|
LOGIN_REQUIRED = None
|
||||||
|
|
||||||
|
|
||||||
def index(req, resp):
|
def index(req, resp):
|
||||||
user = req.env.get('beaker.session', {}).get('user')
|
user = req.env.get('beaker.session', {}).get('user')
|
||||||
if str(user) == 'None' and LOGIN_SPLASH:
|
if user is None and LOGIN_REQUIRED:
|
||||||
resp.content_type = 'text/html'
|
resp.content_type = 'text/html'
|
||||||
resp.body = jinja2_env.get_template('loginsplash.html').render()
|
resp.body = jinja2_env.get_template('loginsplash.html').render()
|
||||||
else:
|
else:
|
||||||
@@ -110,6 +110,8 @@ def secure_filename(filename):
|
|||||||
|
|
||||||
|
|
||||||
class StaticResource(object):
|
class StaticResource(object):
|
||||||
|
allow_no_auth = True
|
||||||
|
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
self.path = path.lstrip('/')
|
self.path = path.lstrip('/')
|
||||||
|
|
||||||
@@ -135,12 +137,12 @@ def init(application, config):
|
|||||||
global HEADER_COLOR
|
global HEADER_COLOR
|
||||||
global IRIS_PLAN_SETTINGS
|
global IRIS_PLAN_SETTINGS
|
||||||
global USERCONTACT_UI_READONLY
|
global USERCONTACT_UI_READONLY
|
||||||
global LOGIN_SPLASH
|
global LOGIN_REQUIRED
|
||||||
SLACK_INSTANCE = config.get('slack_instance')
|
SLACK_INSTANCE = config.get('slack_instance')
|
||||||
HEADER_COLOR = config.get('header_color', '#3a3a3a')
|
HEADER_COLOR = config.get('header_color', '#3a3a3a')
|
||||||
IRIS_PLAN_SETTINGS = config.get('iris_plan_integration')
|
IRIS_PLAN_SETTINGS = config.get('iris_plan_integration')
|
||||||
USERCONTACT_UI_READONLY = config.get('usercontact_ui_readonly', True)
|
USERCONTACT_UI_READONLY = config.get('usercontact_ui_readonly', True)
|
||||||
LOGIN_SPLASH = config.get('force_login_splash')
|
LOGIN_REQUIRED = config.get('require_auth', True)
|
||||||
|
|
||||||
application.add_sink(index, '/')
|
application.add_sink(index, '/')
|
||||||
application.add_route('/static/bundles/{filename}',
|
application.add_route('/static/bundles/{filename}',
|
||||||
|
|||||||
Reference in New Issue
Block a user