Skip to content

Commit

Permalink
Merge pull request #72 from guardian/python-flask-cors
Browse files Browse the repository at this point in the history
Use Flask Cors python library
  • Loading branch information
satterly committed Jan 15, 2015
2 parents 3dc781c + 5c1f689 commit 4218499
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 85 deletions.
3 changes: 3 additions & 0 deletions alerta/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging

from flask import Flask
from flask.ext.cors import CORS

from alerta.version import __version__

Expand All @@ -25,6 +26,8 @@
app.logger.addHandler(stderr_handler)
app.logger.setLevel(logging.INFO)

cors = CORS(app)

app.logger.info('Starting alerta version %s ...', __version__)

from alerta.app.database import Mongo
Expand Down
19 changes: 12 additions & 7 deletions alerta/app/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

from datetime import datetime, timedelta
from functools import wraps
from flask import g, request, jsonify
from jwt import DecodeError, ExpiredSignature
from flask import g, request
from flask.ext.cors import cross_origin
from jwt import DecodeError, ExpiredSignature, InvalidAudience
from base64 import urlsafe_b64decode
from urlparse import parse_qsl

from alerta.app import app, db
from alerta.app.utils import crossdomain, DateEncoder
from alerta.app.utils import jsonify, jsonp, DateEncoder


def verify_api_key(key):
Expand All @@ -32,12 +33,12 @@ def create_token(user, name, email, provider=None):
'email': email,
'provider': provider
}
token = jwt.encode(payload, app.config['SECRET_KEY'], json_encoder=DateEncoder)
token = jwt.encode(payload, key=app.config['SECRET_KEY'], json_encoder=DateEncoder)
return token.decode('unicode_escape')


def parse_token(token):
return jwt.decode(token, app.config['SECRET_KEY'])
return jwt.decode(token, key=app.config['SECRET_KEY'], audience=app.config['OAUTH2_CLIENT_ID'])


def authenticate(message):
Expand Down Expand Up @@ -75,6 +76,8 @@ def decorated(*args, **kwargs):
return authenticate('Token is invalid')
except ExpiredSignature:
return authenticate('Token has expired')
except InvalidAudience:
return authenticate('Invalid audience')
g.user_id = payload['sub']
return f(*args, **kwargs)

Expand All @@ -83,7 +86,8 @@ def decorated(*args, **kwargs):
return decorated

@app.route('/auth/google', methods=['OPTIONS', 'POST'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'])
@cross_origin()
@jsonp
def google():
access_token_url = 'https://accounts.google.com/o/oauth2/token'
people_api_url = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect'
Expand Down Expand Up @@ -122,7 +126,8 @@ def google():
return jsonify(token=token)

@app.route('/auth/github', methods=['OPTIONS', 'POST'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'])
@cross_origin()
@jsonp
def github():
access_token_url = 'https://github.com/login/oauth/access_token'
users_api_url = 'https://api.github.com/user'
Expand Down
14 changes: 7 additions & 7 deletions alerta/app/management/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import logging

from flask import request, Response, url_for, jsonify, render_template
from flask.ext.cors import cross_origin

from alerta.app import app, db
from alerta.app.switch import Switch, SwitchState
from alerta.app.utils import crossdomain
from alerta.app.metrics import Gauge, Counter, Timer
from alerta import build
from alerta.version import __version__
Expand All @@ -24,7 +24,7 @@
started = time.time() * 1000

@app.route('/management', methods=['OPTIONS', 'GET'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'])
@cross_origin()
def management():

endpoints = [
Expand All @@ -38,7 +38,7 @@ def management():


@app.route('/management/manifest', methods=['OPTIONS', 'GET'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'])
@cross_origin()
def manifest():

manifest = {
Expand All @@ -56,7 +56,7 @@ def manifest():


@app.route('/management/properties', methods=['OPTIONS', 'GET'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'])
@cross_origin()
def properties():

properties = ''
Expand All @@ -71,7 +71,7 @@ def properties():


@app.route('/management/switchboard', methods=['OPTIONS', 'GET', 'POST'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'])
@cross_origin()
def switchboard():

if request.method == 'POST':
Expand All @@ -94,7 +94,7 @@ def switchboard():


@app.route('/management/healthcheck', methods=['OPTIONS', 'GET'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'])
@cross_origin()
def health_check():

try:
Expand All @@ -115,7 +115,7 @@ def health_check():


@app.route('/management/status', methods=['OPTIONS', 'GET'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'])
@cross_origin()
def status():

total_alert_gauge.set(db.get_count())
Expand Down
43 changes: 0 additions & 43 deletions alerta/app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,49 +166,6 @@ def parse_fields(r):
return query, sort, group, limit, query_time


def crossdomain(origin=None, methods=None, headers=None,
max_age=21600, attach_to_all=True,
automatic_options=True):
if methods is not None:
methods = ', '.join(sorted(x.upper() for x in methods))
if headers is not None and not isinstance(headers, basestring):
headers = ', '.join(x.upper() for x in headers)
if not isinstance(origin, basestring):
origin = ', '.join(origin)
if isinstance(max_age, timedelta):
max_age = max_age.total_seconds()

def get_methods():
if methods is not None:
return methods

options_resp = current_app.make_default_options_response()
return options_resp.headers['allow']

def decorator(f):
def wrapped_function(*args, **kwargs):
if automatic_options and request.method == 'OPTIONS':
resp = current_app.make_default_options_response()
else:
resp = make_response(f(*args, **kwargs))
if not attach_to_all and request.method != 'OPTIONS':
return resp

h = resp.headers

h['Access-Control-Allow-Origin'] = origin
h['Access-Control-Allow-Methods'] = get_methods()
h['Access-Control-Allow-Credentials'] = 'true'
h['Access-Control-Max-Age'] = str(max_age)
if headers is not None:
h['Access-Control-Allow-Headers'] = headers
return resp

f.provide_automatic_options = False
return update_wrapper(wrapped_function, f)
return decorator


def process_alert(incomingAlert):

for plugin in plugins:
Expand Down
Loading

0 comments on commit 4218499

Please sign in to comment.