1
0
mirror of https://github.com/linkedin/oncall.git synced 2025-11-26 23:10:47 +02:00

Implement auth_required to force auth on API calls (#216)

This commit is contained in:
Daniel Wang
2018-10-04 10:53:48 -07:00
committed by Joe Gillotti
parent c05869581d
commit 40982732fe
5 changed files with 35 additions and 10 deletions

View File

@@ -178,8 +178,10 @@ iris_plan_integration:
# Configures whether Slack settings will appear in the frontend
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.
force_login_splash: False
# Setting to determine whether the Oncall API/frontend is available unauthenticated.
# 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

View File

@@ -11,7 +11,7 @@ import re
from beaker.middleware import SessionMiddleware
from falcon_cors import CORS
from . import db, constants, iris
from . import db, constants, iris, auth
import logging
logger = logging.getLogger('oncall.app')
@@ -47,17 +47,35 @@ class ReqBodyMiddleware(object):
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
def init_falcon_api(config):
global application
cors = CORS(allow_origins_list=config.get('allow_origins_list', []))
application = falcon.API(middleware=[
middlewares = [
SecurityHeaderMiddleware(),
ReqBodyMiddleware(),
cors.middleware
])
]
if config.get('require_auth'):
middlewares.append(AuthMiddleware())
application = falcon.API(middleware=middlewares)
application.req_options.auto_parse_form_urlencoded = False
application.set_error_serializer(json_error_serializer)
from .auth import init as init_auth

View File

@@ -241,8 +241,9 @@ def init(application, config):
check_calendar_auth_by_id = lambda x, y: True
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
# Also replace if require_auth is True, since AuthMiddleware already handles login for us
global login_required
login_required = lambda x: x
else:

View File

@@ -11,6 +11,8 @@ from oncall import db
from random import SystemRandom
from . import auth_manager
allow_no_auth = True
def on_post(req, resp):
login_info = uri.parse_query_string(req.context['body'])

View File

@@ -73,12 +73,12 @@ SLACK_INSTANCE = None
HEADER_COLOR = None
IRIS_PLAN_SETTINGS = None
USERCONTACT_UI_READONLY = None
LOGIN_SPLASH = None
LOGIN_REQUIRED = None
def index(req, resp):
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.body = jinja2_env.get_template('loginsplash.html').render()
else:
@@ -110,6 +110,8 @@ def secure_filename(filename):
class StaticResource(object):
allow_no_auth = True
def __init__(self, path):
self.path = path.lstrip('/')
@@ -135,12 +137,12 @@ def init(application, config):
global HEADER_COLOR
global IRIS_PLAN_SETTINGS
global USERCONTACT_UI_READONLY
global LOGIN_SPLASH
global LOGIN_REQUIRED
SLACK_INSTANCE = config.get('slack_instance')
HEADER_COLOR = config.get('header_color', '#3a3a3a')
IRIS_PLAN_SETTINGS = config.get('iris_plan_integration')
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_route('/static/bundles/{filename}',